Inoltro come POST a una pagina php quanto segue:
{a:1}
Questo è il corpo della richiesta (una richiesta POST).
In php, cosa devo fare per estrarre quel valore?
var_dump($_POST);
non è la soluzione, non funziona.
Inoltro come POST a una pagina php quanto segue:
{a:1}
Questo è il corpo della richiesta (una richiesta POST).
In php, cosa devo fare per estrarre quel valore?
var_dump($_POST);
non è la soluzione, non funziona.
Risposte:
Per accedere al corpo dell'entità di una richiesta POST o PUT (o qualsiasi altro metodo HTTP):
$entityBody = file_get_contents('php://input');
Inoltre, la STDINcostante è un flusso già aperto a php://input, quindi puoi alternativamente fare:
$entityBody = stream_get_contents(STDIN);
Dalla voce manuale di PHP sui documenti degli stream I / O :
php: // input è un flusso di sola lettura che consente di leggere dati non elaborati dal corpo della richiesta. Nel caso di richieste POST, è preferibile utilizzare php: // input invece
$HTTP_RAW_POST_DATAche non dipende da direttive speciali php.ini. Inoltre, per quei casi in cui$HTTP_RAW_POST_DATAnon è popolato per impostazione predefinita, è un'alternativa potenzialmente meno intensiva della memoria all'attivazione di always_populate_raw_post_data. php: // input non è disponibile con enctype = "multipart / form-data".
In particolare, tieni presente che lo php://inputstream, indipendentemente dal modo in cui accedi a un SAPI Web, non è ricercabile . Ciò significa che può essere letto solo una volta. Se lavori in un ambiente in cui i corpi di entità HTTP di grandi dimensioni vengono caricati di routine, potresti voler mantenere l'input nella sua forma di flusso (piuttosto che memorizzarlo come nel primo esempio sopra).
Per mantenere la risorsa di flusso qualcosa di simile può essere 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://tempconsente di gestire il consumo di memoria perché passerà in modo trasparente all'archiviazione del file system dopo aver memorizzato una determinata quantità di dati (2 M per impostazione predefinita). Questa dimensione può essere manipolata nel file php.ini o aggiungendo/maxmemory:NNNN , in byte , la quantità massima di dati da conservare in memoria prima di utilizzare un file temporaneo.
Naturalmente, a meno che tu non abbia una buona ragione per cercare nel flusso di input, non dovresti aver bisogno di questa funzionalità in un'applicazione web. La lettura del corpo dell'entità della richiesta HTTP in genere è sufficiente: non tenere i clienti in attesa tutto il giorno mentre l'app capisce cosa fare.
Si noti che php: // input non è disponibile per le richieste che specificano Content-Type: multipart/form-dataun'intestazione ( enctype="multipart/form-data"in moduli HTML). Ciò deriva dal fatto che PHP ha già analizzato i dati del modulo nel $_POSTsuperglobal.
php://inputè vuoto anche per il application/x-www-form-urlencodedtipo di contenuto (oltre multipart/form-data)
php://inputè. Quindi, mentre le configurazioni CGI (veloci) stream_get_contents(STDIN)non funzioneranno, lo file_get_contents("php://input")faranno.
restituisce valore nella matrice
$data = json_decode(file_get_contents('php://input'), true);
$datamatrice associativa per verificare se ogni valore è codificato nel modo desiderato. Il modo "stream-to-datatype" di guardare le cose può essere semplicistico, ma potrebbe non essere efficiente come gestire la codifica nella "forma stream" usando un filtro stream. Se non si gestiscono problemi di codifica e semplicemente la sanificazione e la convalida, manca un passaggio.
Una possibile ragione per un vuoto $_POSTè che la richiesta non è POST, o non POSTpiù ... Potrebbe essere iniziata come posta, ma ha incontrato 301o 302reindirizzato da qualche parte, che è passato a GET!
Ispezionare $_SERVER['REQUEST_METHOD']per verificare se questo è il caso.
Vedi https://stackoverflow.com/a/19422232/109787 per una buona discussione sul perché questo non dovrebbe accadere ma continua a farlo.
POSTma dopo l'ispezione stava dimostrando che lo era GET. Una volta aggiunto /a alla fine del mio URL, ha iniziato a mostrare POST. Strano!
Controlla la $HTTP_RAW_POST_DATAvariabile
php://input. $HTTP_RAW_POST_DATAnon è disponibile con enctype="multipart/form-data".
Se è stata installata l'estensione HTTP PECL, è possibile utilizzare la http_get_request_body()funzione per ottenere i dati del corpo come stringa.
Se hai installato l'estensione pecl / http , puoi anche usare questo:
$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è false, che una matrice vuota deve essere restituito. Cosa succede se qualcuno ha inviato XML o YAML? Aggiungi un test per il Content-Type e vai da lì.
$_SERVERsuperglobal per i valori utili da controllare.
http_get_request_body()è stato esplicitamente creato per ottenere il corpo PUTe le POSTrichieste secondo la documentazione http://php.net/manual/fa/function.http-get-request-body.php
$_POSTsuperglobal. Questo è anche (soprattutto) vero nel caso di richieste PUT, poiché PHP non ha superglobal corrispondente.