Ricevi POST JSON con PHP


292

Sto cercando di ricevere un POST JSON su un sito Web di interfaccia di pagamento, ma non riesco a decodificarlo.

Quando stampo:

echo $_POST;

Ottengo:

Array

Non ottengo nulla quando provo questo:

if ( $_POST ) {
    foreach ( $_POST as $key => $value ) {
        echo "llave: ".$key."- Valor:".$value."<br />";
    }
}

Non ottengo nulla quando provo questo:

$string = $_POST['operation'];
$var = json_decode($string);
echo $var;

Ottengo NULL quando provo questo:

$data = json_decode( file_get_contents('php://input') );
var_dump( $data->operation );

Quando io faccio:

$data = json_decode(file_get_contents('php://input'), true);
var_dump($data);

Ottengo:

NULL

Il formato JSON è (secondo la documentazione del sito di pagamento):

{
   "operacion": {
       "tok": "[generated token]",
       "shop_id": "12313",
       "respuesta": "S",
       "respuesta_details": "respuesta S",
       "extended_respuesta_description": "respuesta extendida",
       "moneda": "PYG",
       "monto": "10100.00",
       "authorization_number": "123456",
       "ticket_number": "123456789123456",
       "response_code": "00",
       "response_description": "Transacción aprobada.",
       "security_information": {
           "customer_ip": "123.123.123.123",
           "card_source": "I",
           "card_country": "Croacia",
           "version": "0.3",
           "risk_index": "0"
       }
    }
}

Il registro del sito di pagamento dice che tutto è OK. Qual è il problema?


4
Cosa var_dump($_POST)dice? È un array vuoto?
Sergiu Paraschiv,

3
$ _POST ha il dizionario di "&" richieste di posta separate. $ _POST per json DEFINITAMENTE NON funzionerà. Puoi stampare file_get_contents ('php: // input')? Inoltre è var_dump ($ data-> operazione); o var_dump ($ data-> operacion); ?
Akshaya Shanbhogue,

4
JSON è un testo, perché non dovrebbe essere accessibile in POST? Finché il servizio di pagamento POST invia quel testo al suo endpoint PHP, dovrebbe essere in grado di json_decodefarlo. Ma forse il servizio invia i dati nel corpo della richiesta , questa è una storia diversa e sì, file_get_contents('php://input')allora dovrebbe funzionare.
Sergiu Paraschiv,

1
Se è così, questo è stato discusso qui: stackoverflow.com/questions/8945879/…
Sergiu Paraschiv,

3
$ _POST: una matrice associativa di variabili passata allo script corrente tramite il metodo POST HTTP quando si utilizzano application / x-www-form-urlencoded o multipart / form-data come HTTP Content-Type nella richiesta. Non quando si utilizza application / json.
Cristian Sepulveda,

Risposte:


476

Provare;

$data = json_decode(file_get_contents('php://input'), true);
print_r($data);
echo $data["operacion"];

Dal tuo json e dal tuo codice, sembra che tu abbia scritto correttamente la parola operazione alla tua estremità, ma non è nel json.

MODIFICARE

Forse vale anche la pena provare a fare eco alla stringa json da php: // input.

echo file_get_contents('php://input');

2
Ciao In entrambi i casi non vedo nulla sullo schermo
Pablo Ramirez,

6
Per quello che vale, operacion è l'ortografia (dare o prendere un accento) in spagnolo.
Patrick,

11
Il punto era che non lo scriveva correttamente in entrambi i posti, né operazione né operazione in entrambi i punti.
msj121

2
Prima di PHP 5.6, ottenere il contenuto di php: // input poteva essere fatto solo una volta. Il tuo codice o framework potrebbe averlo aperto da qualche parte prima?
aljo f

90

Se hai già impostato i tuoi parametri come $ _POST ['eg'] per esempio e non desideri cambiarlo, fallo semplicemente in questo modo:

$_POST = json_decode(file_get_contents('php://input'), true);

Questo ti risparmierà il fastidio di cambiare tutto $ _POST in qualcos'altro e ti consentirà di effettuare comunque normali richieste di posta se desideri eliminare questa riga.


1
Grazie Signore. Questo ha funzionato nel mio caso mentre sto postando json da Android a PHP!
Vanurag,

Grazie, ha funzionato nel mio caso. Stavo assegnando i dati $ _POST a una variabile $ request, ora ho appena assegnato a quella variabile il contenuto di php: // input.
Finanziatore

Questo ha reso la mia giornata molto più semplice. Grazie.
Tyler Mammone,

47

Vale la pena sottolineare che se si utilizza json_decode(file_get_contents("php://input"))(come altri hanno già detto), ciò non riuscirà se la stringa non è JSON valida.

Questo può essere semplicemente risolto controllando prima se il JSON è valido. vale a dire

function isValidJSON($str) {
   json_decode($str);
   return json_last_error() == JSON_ERROR_NONE;
}

$json_params = file_get_contents("php://input");

if (strlen($json_params) > 0 && isValidJSON($json_params))
  $decoded_params = json_decode($json_params);

Edit: Si noti che la rimozione di strlen($json_params)cui sopra può causare errori sottili, come json_last_error()non non cambia quando nullo viene passata una stringa vuota, come illustrato di seguito: http://ideone.com/va3u8U


2
Se qualcuno si aspetta una quantità piuttosto grande di dati nell'input e / o un volume elevato di richieste, potrebbe voler estendere la funzione per popolare facoltativamente un riferimento variabile fornito con il risultato di json_decode, in modo che l'analisi non debba essere eseguito due volte su input ben formati.
faintsignal

4
Fatto in questo modo, decodificherai il json due volte. È caro. Con il primo decodifica, è possibile salvare immediatamente il valore decodificato, farlo successivamente (json_last_error () == JSON_ERROR_NONE) e quindi procedere con l'elaborazione se tutto va bene [altrimenti fallire]
kakoma

@kakoma, sicuramente! Questo è stato scritto pensando alla semplicità. Ai fini dell'educazione, la semplicità è spesso più importante dell'efficienza. :)
XtraSimplicity il

1
Vero. Per scopi educativi. Grazie per il chiarimento @XtraSimplicity Ha, è anche a tuo nome :-)
kakoma

37

Usa $HTTP_RAW_POST_DATAinvece di $_POST.

Ti darà i dati POST così come sono.

Sarai in grado di decodificarlo usando in json_decode()seguito.


45
Poiché $ HTTP_RAW_POST_DATA è deprecato ora puoi utilizzare in questo modo per leggere JSON POST$json = file_get_contents('php://input'); $obj = json_decode($json);
Bikal Basnet

2
Per me questa risposta comune [usa $ json = file_get_contents ('php: // input'); ] Vedevo che non funzionava quando JSON veniva inviato con la maggior parte dei "caratteri contenitore" esterni come []. Questa risposta qui con RAW_POST_DATA ha fatto il trucco per me. E va bene con il mio attuale stack PHP. Sono rimasto bloccato per un po '.. grazie mille per questa soluzione!
Gene Bo,

Questo è ancora abbastanza attuale, per i webhook di GitLab (per esempio), devi ancora usare $HTTP_RAW_POST_DATA.
developius

Ho cercato e cercato una soluzione e Bikel Basnet tuo ha funzionato per me. Grazie!
Scooter

questo mi ha salvato i 3 giorni cercando modi per catturare le variabili POST da un HttpClient di Angular 2 inviando una richiesta con il tipo Content-Type: application / json
Frederick G. Sandalo,


8
$data = file_get_contents('php://input');
echo $data;

Questo ha funzionato per me.


-5

Vorrei pubblicare una risposta che utilizza anche curl per ottenere i contenuti e mpdf per salvare i risultati in un pdf, in modo da ottenere tutti i passaggi di un caso d'uso tipico. È solo codice non elaborato (quindi adattato alle tue esigenze), ma funziona.

// import mpdf somewhere
require_once dirname(__FILE__) . '/mpdf/vendor/autoload.php';

// get mpdf instance
$mpdf = new \Mpdf\Mpdf();

// src php file
$mysrcfile = 'http://www.somesite.com/somedir/mysrcfile.php';
// where we want to save the pdf
$mydestination = 'http://www.somesite.com/somedir/mypdffile.pdf';

// encode $_POST data to json
$json = json_encode($_POST);

// init curl > pass the url of the php file we want to pass 
// data to and then print out to pdf
$ch = curl_init($mysrcfile);

// tell not to echo the results
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1 );

// set the proper headers
curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/json', 'Content-Length: ' . strlen($json) ]);

// pass the json data to $mysrcfile
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);

// exec curl and save results
$html = curl_exec($ch);

curl_close($ch);

// parse html and then save to a pdf file
$mpdf->WriteHTML($html);
$this->mpdf->Output($mydestination, \Mpdf\Output\Destination::FILE);

In $ mysrcfile leggerò i dati json in questo modo (come indicato nelle risposte precedenti):

$data = json_decode(file_get_contents('php://input'));
// (then process it and build the page source)

1
Troppe informazioni inutili. Cosa fa il primo codice? Il secondo frammento è la risposta però ...
Fipsi,

@Fipsi, (e per tutti i downvoter) la mia risposta è solo, e ovviamente, un compendio degli altri. E, come ho scritto, un caso d'uso (mpdf). Al momento della stesura, mi sarebbe PIACIUTO AMARE vedere una risposta come questa, mentre cercavo di capire come. E il mio secondo frammento NON è certamente la risposta, poiché per ricevere i dati json, i dati devono anche essere inviati correttamente e non solo ci sono più modi per inviare, ma spesso il modo è proprio il vero problema. In questo caso, il focus non è json_decode, è invece come ottenere correttamente qualcosa da file_get_contents('php://input').
Luca Reghellin,

2
Non ho votato in negativo e capisco la tua intenzione. Ma la domanda è "Ricevi JSON" e non "Invia JSON". È abbastanza chiaro dalla domanda che l'OP ha problemi a ricevere e non è davvero interessato a inviare
Fipsi
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.