Erhalten Sie JSON POST mit PHP

292

Ich versuche, einen JSON-POST auf einer Zahlungsschnittstellen-Website zu erhalten, kann ihn jedoch nicht dekodieren.

Wenn ich drucke:

echo $_POST;

Ich bekomme:

Array

Ich bekomme nichts, wenn ich das versuche:

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

Ich bekomme nichts, wenn ich das versuche:

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

Ich bekomme NULL, wenn ich das versuche:

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

Wenn ich es tue:

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

Ich bekomme:

NULL

Das JSON-Format lautet (gemäß Dokumentation der Zahlungsstelle):

{
   "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"
       }
    }
}

Das Zahlungsprotokoll sagt, dass alles in Ordnung ist. Was ist das Problem?

Pablo Ramirez
quelle
4
Was var_dump($_POST)sagt das aus? Ist es ein leeres Array?
Sergiu Paraschiv
3
$ _POST enthält das Wörterbuch mit "&" getrennten Post-Anfragen. $ _POST für json wird definitiv nicht funktionieren. Können Sie file_get_contents ('php: // input') drucken? Auch ist es var_dump ($ data-> operation); oder var_dump ($ data-> operacion); ?
Akshaya Shanbhogue
4
JSON ist Text. Warum ist er in POST nicht verfügbar? Solange der Zahlungsdienst diesen Text an seinen PHP-Endpunkt sendet, sollte er dazu in der Lage json_decodesein. Aber vielleicht sendet der Dienst Daten im Anfragetext , das ist eine andere Geschichte und ja, file_get_contents('php://input')sollte dann funktionieren.
Sergiu Paraschiv
1
Wenn ja, dann wurde dies hier besprochen: stackoverflow.com/questions/8945879/…
Sergiu Paraschiv
3
$ _POST: Ein assoziatives Array von Variablen, die über die HTTP-POST-Methode an das aktuelle Skript übergeben werden, wenn application / x-www-form-urlencoded oder multipart / form-data als HTTP-Inhaltstyp in der Anforderung verwendet werden. Nicht bei Verwendung von application / json.
Cristian Sepulveda

Antworten:

476

Versuchen;

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

Aus Ihrem JSON und Ihrem Code geht hervor, dass Sie das Wort Operation an Ihrem Ende richtig geschrieben haben , aber es ist nicht im JSON enthalten.

BEARBEITEN

Vielleicht lohnt es sich auch zu versuchen, den json-String von php: // input wiederzugeben.

echo file_get_contents('php://input');
Dom
quelle
2
Hallo In beiden Fällen bekomme ich nichts auf dem Bildschirm
Pablo Ramirez
6
Für das, was es wert ist, ist operacion die Schreibweise (geben oder nehmen Sie einen Akzent) auf Spanisch.
Patrick
11
Sein Punkt war, dass er es an beiden Stellen nicht richtig buchstabierte, weder an der Operation noch an beiden Stellen.
msj121
2
Vor PHP 5.6 konnte der Inhalt der Eingabe von php: // nur einmal abgerufen werden. Könnte Ihr Code oder Framework es schon einmal geöffnet haben?
Aljo f
90

Wenn Sie Ihre Parameter bereits wie $ _POST ['eg'] eingestellt haben und sie nicht ändern möchten, gehen Sie einfach so vor:

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

Dies erspart Ihnen den Aufwand, alle $ _POST in etwas anderes zu ändern, und ermöglicht es Ihnen, weiterhin normale Post-Anfragen zu stellen, wenn Sie diese Zeile entfernen möchten.

Steve Chan
quelle
1
Danke mein Herr. Dies hat in meinem Fall funktioniert, da ich JSON-Posts von Android auf PHP mache!
Vanurag
Danke, es hat in meinem Fall funktioniert. Ich habe die $ _POST-Daten einer $ request-Variablen zugewiesen, jetzt habe ich dieser Variablen nur den Inhalt der Eingabe von php: // zugewiesen.
Funder
Das hat meinen Tag so viel einfacher gemacht. Vielen Dank.
Tyler Mammone
47

Es ist erwähnenswert, dass bei Verwendung json_decode(file_get_contents("php://input"))(wie bereits erwähnt) dies fehlschlägt, wenn die Zeichenfolge nicht gültig ist.

Dies kann einfach behoben werden, indem zunächst überprüft wird, ob der JSON gültig ist. dh

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);

Bearbeiten: Beachten Sie, dass das Entfernen von strlen($json_params)oben zu geringfügigen Fehlern führen kann, da json_last_error()sich nichts ändert, wenn nulleine leere Zeichenfolge übergeben wird, wie hier gezeigt: http://ideone.com/va3u8U

XtraSimplicity
quelle
2
Wenn jemand eine ziemlich große Datenmenge in der Eingabe und / oder ein hohes Anforderungsvolumen erwartet, möchte er die Funktion möglicherweise erweitern, um optional eine bereitgestellte Variablenreferenz mit dem Ergebnis von json_decode zu füllen, sodass das Parsen nicht erforderlich ist zweimal an wohlgeformten Eingaben durchgeführt werden.
Ohnmachtssignal
4
Auf diese Weise dekodieren Sie den JSON tatsächlich zweimal. Das ist teuer. Mit der ersten Dekodierung können Sie den dekodierten Wert sofort speichern, diese Prüfung anschließend durchführen (json_last_error () == JSON_ERROR_NONE) und dann mit der Verarbeitung fortfahren, wenn alles in
Ordnung
@ Kakoma, auf jeden Fall! Dies wurde mit Blick auf die Einfachheit geschrieben. Für Bildungszwecke ist Einfachheit oft wichtiger als Effizienz. :)
XtraSimplicity
1
Wahr. Für Bildungszwecke. Vielen Dank für die Klarstellung @XtraSimplicity Ha, es ist sogar in Ihrem Namen :-)
Kakoma
37

Verwenden Sie $HTTP_RAW_POST_DATAanstelle von $_POST.

Sie erhalten POST-Daten wie sie sind.

Sie können es json_decode()später mit dekodieren .

Urisavka
quelle
45
Da $ HTTP_RAW_POST_DATA jetzt abgeschrieben ist, können Sie auf diese Weise JSON POST$json = file_get_contents('php://input'); $obj = json_decode($json);
Bikal Basnet
2
Für mich diese allgemeine Antwort [benutze $ json = file_get_contents ('php: // input'); ] Ich habe gesehen, dass es nicht funktioniert hat, als der JSON mit den äußersten "Containerzeichen" als [] gesendet wurde. Diese Antwort hier mit RAW_POST_DATA hat den Trick für mich getan. Und ist in Ordnung mit meinem aktuellen PHP-Stack. Ich steckte eine Weile fest. Vielen Dank für diese Lösung!
Gene Bo
Dies ist immer noch ziemlich aktuell, für GitLab- Webhooks (zum Beispiel) müssen Sie noch verwenden $HTTP_RAW_POST_DATA.
Developius
Ich habe nach einer Lösung gesucht und Bikel Basnet hat für mich gearbeitet. Vielen Dank!
Roller
Dies ersparte mir 3 Tage bei der Suche nach Möglichkeiten, die POST-Variablen von einem HttpClient von Angular 2 abzufangen, der eine Anfrage mit dem Typ Inhaltstyp: application / json
Frederick G. Sandalo
8
$data = file_get_contents('php://input');
echo $data;

Das hat bei mir funktioniert.

HyperCoder
quelle
-5

Ich möchte eine Antwort veröffentlichen, die auch Curl verwendet, um den Inhalt abzurufen , und mpdf , um die Ergebnisse in einem PDF zu speichern, damit Sie alle Schritte eines typischen Anwendungsfalls erhalten. Es ist nur Rohcode (um an Ihre Bedürfnisse angepasst zu werden), aber es funktioniert.

// 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 lese ich json-Daten wie folgt (wie in den vorherigen Antworten angegeben):

$data = json_decode(file_get_contents('php://input'));
// (then process it and build the page source)
Luca Reghellin
quelle
1
Zu viele nutzlose Informationen. Was macht der erste Code? Der zweite Ausschnitt ist die Antwort auf ...
Fipsi
@Fipsi (und allen Downvotern) meine Antwort ist nur und ganz offensichtlich ein Kompendium der anderen. Und, wie ich schrieb, ein Anwendungsfall (mpdf). Zum Zeitpunkt des Schreibens hätte ich es geliebt, eine Antwort wie diese zu sehen, als ich versuchte herauszufinden, wie es geht. Und mein zweites Snippet ist sicherlich NICHT die Antwort, denn um JSON-Daten zu empfangen, müssen die Daten auch ordnungsgemäß gesendet werden, und es gibt nicht nur mehr Möglichkeiten zum Senden, sondern oft ist der Weg genau das eigentliche Problem. In diesem Fall liegt der Fokus nicht auf json_decode, sondern darauf, wie man etwas richtig herausholt file_get_contents('php://input').
Luca Reghellin
2
Ich habe nicht abgelehnt und ich verstehe Ihre Absicht. Aber die Frage ist "JSON empfangen" und nicht "JSON senden". Aus der Frage geht ziemlich klar hervor, dass das OP Probleme beim Empfangen hat und nicht wirklich am Senden interessiert ist
Fipsi