Je soumets en tant que POST à une page php ce qui suit:
{a:1}
Il s'agit du corps de la demande (une demande POST).
En php, que dois-je faire pour extraire cette valeur?
var_dump($_POST);
n'est pas la solution, ne fonctionne pas.
Je soumets en tant que POST à une page php ce qui suit:
{a:1}
Il s'agit du corps de la demande (une demande POST).
En php, que dois-je faire pour extraire cette valeur?
var_dump($_POST);
n'est pas la solution, ne fonctionne pas.
Réponses:
Pour accéder au corps d'entité d'une demande POST ou PUT (ou à toute autre méthode HTTP):
$entityBody = file_get_contents('php://input');
De plus, la STDIN
constante est un flux déjà ouvert vers php://input
, vous pouvez donc également faire:
$entityBody = stream_get_contents(STDIN);
À partir de l' entrée manuelle PHP sur les documents de flux d'E / S :
php: // input est un flux en lecture seule qui vous permet de lire les données brutes du corps de la requête. Dans le cas des requêtes POST, il est préférable d'utiliser l' entrée php: // au lieu de
$HTTP_RAW_POST_DATA
cela car cela ne dépend pas de directives php.ini spéciales. De plus, pour les cas où il$HTTP_RAW_POST_DATA
n'est pas renseigné par défaut, il s'agit d'une alternative potentiellement moins gourmande en mémoire à l'activation de always_populate_raw_post_data. php: // entrée n'est pas disponible avec enctype = "multipart / form-data".
Plus précisément, vous voudrez noter que le php://input
flux, quelle que soit la façon dont vous y accédez dans un SAPI Web, n'est pas recherché . Cela signifie qu'il ne peut être lu qu'une seule fois. Si vous travaillez dans un environnement où de grands corps d'entités HTTP sont régulièrement téléchargés, vous souhaiterez peut-être conserver l'entrée sous sa forme de flux (plutôt que de la mettre en mémoire tampon comme dans le premier exemple ci-dessus).
Pour maintenir la ressource de flux, quelque chose comme ceci peut être utile:
<?php
function detectRequestBody() {
$rawInput = fopen('php://input', 'r');
$tempStream = fopen('php://temp', 'r+');
stream_copy_to_stream($rawInput, $tempStream);
rewind($tempStream);
return $tempStream;
}
php://temp
vous permet de gérer la consommation de mémoire car il basculera de manière transparente vers le stockage du système de fichiers après le stockage d'une certaine quantité de données (2 Mo par défaut). Cette taille peut être manipulée dans le fichier php.ini ou en ajoutant /maxmemory:NN
, où NN
est la quantité maximale de données à conserver en mémoire avant d'utiliser un fichier temporaire, en octets.
Bien sûr, à moins d'avoir une très bonne raison de rechercher sur le flux d'entrée, vous ne devriez pas avoir besoin de cette fonctionnalité dans une application Web. La lecture du corps de l'entité de demande HTTP une fois suffit généralement - ne laissez pas les clients attendre toute la journée pendant que votre application trouve quoi faire.
Notez que l'entrée php: // n'est pas disponible pour les demandes spécifiant un en- Content-Type: multipart/form-data
tête ( enctype="multipart/form-data"
dans les formulaires HTML). Cela résulte du fait que PHP a déjà analysé les données du formulaire dans le $_POST
superglobal.
php://input
est également vide pour le application/x-www-form-urlencoded
type de contenu (en plus multipart/form-data
)
php://input
est. Ainsi, alors que les configurations CGI (rapides) stream_get_contents(STDIN)
ne fonctionneront pas, elles le file_get_contents("php://input")
seront.
retourne la valeur dans le tableau
$data = json_decode(file_get_contents('php://input'), true);
$data
tableau associatif pour vérifier si chaque valeur est codée comme vous le souhaitez. La façon de voir les choses de «flux vers type de données» peut être simpliste, mais elle peut ne pas être aussi efficace que de traiter le codage sous la «forme de flux» à l'aide d'un filtre de flux. Si vous ne gérez pas les problèmes d'encodage et que vous désinfectez et validez simplement, il vous manque une étape.
Une raison possible pour un vide $_POST
est que la demande ne l'est pas POST
, ou POST
plus ... Elle peut avoir commencé en tant que publication, mais a rencontré un 301
ou 302
rediriger quelque part, qui est basculé vers GET
!
Inspectez $_SERVER['REQUEST_METHOD']
pour vérifier si c'est le cas.
Voir https://stackoverflow.com/a/19422232/109787 pour une bonne discussion sur la raison pour laquelle cela ne devrait pas se produire, mais se produit toujours.
POST
mais après inspection, elle montrait que c'était le cas GET
. Une fois que j'ai ajouté un /
à la fin de mon URL, il a commencé à afficher POST. Bizarre!
Vérifiez la $HTTP_RAW_POST_DATA
variable
php://input
. $HTTP_RAW_POST_DATA
n'est pas disponible avec enctype="multipart/form-data"
.
Si vous avez installé l'extension HTTP PECL, vous pouvez utiliser la http_get_request_body()
fonction pour obtenir les données du corps sous forme de chaîne.
Si vous avez installé l'extension pecl / http , vous pouvez également utiliser ceci:
$request = new http\Env\Request();
$request->getBody();
function getPost()
{
if(!empty($_POST))
{
// when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request
// NOTE: if this is the case and $_POST is empty, check the variables_order in php.ini! - it must contain the letter P
return $_POST;
}
// when using application/json as the HTTP Content-Type in the request
$post = json_decode(file_get_contents('php://input'), true);
if(json_last_error() == JSON_ERROR_NONE)
{
return $post;
}
return [];
}
print_r(getPost());
json_last_error() == JSON_ERROR_NONE
est false
, qu'un tableau vide doit être retourné. Que faire si quelqu'un a soumis du XML ou du YAML? Ajoutez un test pour le Content-Type et continuez à partir de là.
$_SERVER
superglobal pour les valeurs utiles à vérifier.
http_get_request_body()
a été explicitement faite pour obtenir le corps de PUT
et les POST
demandes selon la documentation http://php.net/manual/fa/function.http-get-request-body.php
$_POST
superglobal. Cela est également (particulièrement) vrai dans le cas des requêtes PUT, car PHP n'a pas de superglobal correspondant.