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 STDIN
costante è 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_DATA
che non dipende da direttive speciali php.ini. Inoltre, per quei casi in cui$HTTP_RAW_POST_DATA
non è 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://input
stream, 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://temp
consente 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:NN
NN
, 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-data
un'intestazione ( enctype="multipart/form-data"
in moduli HTML). Ciò deriva dal fatto che PHP ha già analizzato i dati del modulo nel $_POST
superglobal.
php://input
è vuoto anche per il application/x-www-form-urlencoded
tipo 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);
$data
matrice 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 POST
più ... Potrebbe essere iniziata come posta, ma ha incontrato 301
o 302
reindirizzato 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.
POST
ma 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_DATA
variabile
php://input
. $HTTP_RAW_POST_DATA
non è 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ì.
$_SERVER
superglobal per i valori utili da controllare.
http_get_request_body()
è stato esplicitamente creato per ottenere il corpo PUT
e le POST
richieste secondo la documentazione http://php.net/manual/fa/function.http-get-request-body.php
$_POST
superglobal. Questo è anche (soprattutto) vero nel caso di richieste PUT, poiché PHP non ha superglobal corrispondente.