Terima JSON POST dengan PHP

292

Saya mencoba menerima JSON POST di situs web antarmuka pembayaran, tetapi saya tidak dapat mendekodekannya.

Ketika saya mencetak:

echo $_POST;

Saya mendapat:

Array

Saya tidak mendapatkan apa-apa ketika saya mencoba ini:

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

Saya tidak mendapatkan apa-apa ketika saya mencoba ini:

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

Saya mendapatkan NULL ketika saya mencoba ini:

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

Ketika saya melakukannya:

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

Saya mendapat:

NULL

Format JSON adalah (sesuai dengan dokumentasi situs pembayaran):

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

Log situs pembayaran mengatakan semuanya OK. Apa masalahnya?

Pablo Ramirez
sumber
4
Apa yang var_dump($_POST)dikatakan? Apakah ini array kosong?
Sergiu Paraschiv
3
$ _POST memiliki kamus "&" permintaan pos yang dipisahkan. $ _POST untuk json akan PASTI tidak bekerja. Bisakah Anda mencetak file_get_contents ('php: // input')? Juga itu var_dump ($ data-> operasi); atau var_dump ($ data-> operacion); ?
Akshaya Shanbhogue
4
JSON adalah teks, mengapa itu tidak dapat diakses di POST? Selama layanan pembayaran POST teks ke titik akhir PHP-nya maka ia harus bisa json_decode. Tapi mungkin layanan mengirimkan data di badan permintaan , itu cerita yang berbeda dan ya, file_get_contents('php://input')harusnya berhasil.
Sergiu Paraschiv
1
Jika demikian maka ini telah dibahas di sini: stackoverflow.com/questions/8945879/…
Sergiu Paraschiv
3
$ _POST: Array asosiatif variabel yang diteruskan ke skrip saat ini melalui metode HTTP POST saat menggunakan aplikasi / x-www-form-urlencoded atau multipart / form-data sebagai Tipe Konten HTTP dalam permintaan. Tidak ketika menggunakan aplikasi / json.
Cristian Sepulveda

Jawaban:

476

Mencoba;

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

Dari json Anda dan kode Anda, sepertinya Anda telah mengeja kata operasi dengan benar di ujung Anda, tetapi tidak ada di json.

EDIT

Mungkin juga patut untuk mencoba menggaungkan string json dari php: // input.

echo file_get_contents('php://input');
Dom
sumber
2
Hai Dalam kedua kasus saya tidak mendapatkan apa-apa di layar
Pablo Ramirez
6
Untuk apa nilainya, operacion adalah ejaan (memberi atau menerima aksen) dalam bahasa Spanyol.
Patrick
11
Maksudnya adalah bahwa dia tidak mengejanya dengan benar di kedua tempat, baik operacion atau operasi di kedua tempat.
msj121
2
Sebelum PHP 5.6, mendapatkan konten php: // input hanya bisa dilakukan sekali. Bisakah kode atau kerangka kerja Anda pernah membukanya di suatu tempat sebelumnya?
aljo f
90

Jika Anda sudah menetapkan parameter Anda seperti $ _POST ['mis.'] Misalnya dan Anda tidak ingin mengubahnya, lakukan saja seperti ini:

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

Ini akan menghemat kerumitan Anda mengubah semua $ _POST menjadi sesuatu yang lain dan memungkinkan Anda untuk tetap membuat permintaan posting normal jika Anda ingin mengeluarkan garis ini.

Steve Chan
sumber
1
Terima kasih Pak. Ini berhasil dalam kasus saya karena saya melakukan posting json dari Android ke PHP!
vanurag
Terima kasih, itu berhasil dalam kasus saya. Saya menugaskan data $ _POST ke variabel $ request, sekarang saya baru saja ditugaskan ke variabel itu isi php: // input.
Funder
Ini hanya membuat hari saya jadi lebih mudah. Terima kasih.
Tyler Mammone
47

Perlu ditunjukkan bahwa jika Anda menggunakan json_decode(file_get_contents("php://input"))(seperti yang telah disebutkan orang lain), ini akan gagal jika string tidak valid JSON.

Ini dapat dengan mudah diselesaikan dengan terlebih dahulu memeriksa apakah JSON valid. yaitu

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: Perhatikan bahwa menghapus strlen($json_params)atas mungkin mengakibatkan kesalahan yang halus, seperti json_last_error()tidak tidak berubah ketika nullatau string kosong dilewatkan, seperti yang ditunjukkan di sini: http://ideone.com/va3u8U

Kesederhanaan Xtra
sumber
2
Jika seseorang mengharapkan sejumlah besar data dalam input dan / atau volume permintaan yang tinggi, mereka mungkin ingin memperluas fungsi untuk secara opsional mengisi referensi variabel yang disediakan dengan hasil json_decode, sehingga penguraian tidak perlu dilakukan dua kali pada input yang dibentuk dengan baik.
faintsignal
4
Dilakukan dengan cara ini, Anda benar-benar memecahkan kode json dua kali. Itu mahal. Dengan decode pertama, Anda dapat langsung menyimpan nilai yang didekodekan, lakukan pengecekan sesudahnya (json_last_error () == JSON_ERROR_NONE) dan kemudian lanjutkan dengan pemrosesan jika semuanya baik-baik saja [gagal kalau tidak]
kakoma
@ Kanoma, pasti! Ini ditulis dengan kesederhanaan dalam pikiran. Untuk tujuan pendidikan, kesederhanaan seringkali lebih penting daripada efisiensi. :)
XtraSimplicity
1
Benar. Untuk tujuan pendidikan. Terima kasih atas klarifikasi @XtraSimplicity Ha, itu bahkan atas nama Anda :-)
kakoma
37

Gunakan $HTTP_RAW_POST_DATAsebagai ganti $_POST.

Ini akan memberi Anda data POST apa adanya.

Anda akan dapat mendekode menggunakan itu json_decode()nanti.

Urisavka
sumber
45
Karena $ HTTP_RAW_POST_DATA didepresiasi sekarang, Anda dapat menggunakan cara ini untuk membaca JSON POST$json = file_get_contents('php://input'); $obj = json_decode($json);
Bikal Basnet
2
Bagi saya jawaban umum ini [gunakan $ json = file_get_contents ('php: // input'); ] Saya melihat tidak berfungsi ketika JSON dikirim dengan sebagian besar "wadah kontainer" sebagai []. Jawaban di sini dengan RAW_POST_DATA membantu saya. Dan tidak masalah dengan tumpukan PHP saya saat ini. Saya macet sebentar .. terima kasih banyak atas solusi ini!
Gene Bo
Ini masih cukup baru, untuk webhook GitLab (misalnya), Anda masih harus menggunakan $HTTP_RAW_POST_DATA.
developius
Saya mencari dan mencari solusi dan Bikel Basnet milik Anda bekerja untuk saya. Terima kasih!
Scooter
ini menyelamatkan 3 hari saya mencari cara untuk menangkap variabel POST dari HttpClient of Angular 2 mengirimkan permintaan dengan tipe Content-Type: application / json
Frederick G. Sandalo
8
$data = file_get_contents('php://input');
echo $data;

Ini berhasil untuk saya.

hyperCoder
sumber
-5

Saya ingin memposting jawaban yang juga menggunakan curl untuk mendapatkan konten, dan mpdf untuk menyimpan hasilnya ke pdf, sehingga Anda mendapatkan semua langkah dari use case tipical. Ini hanya kode mentah (jadi disesuaikan dengan kebutuhan Anda), tetapi ia berfungsi.

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

Dalam $ mysrcfile saya akan membaca data json seperti ini (sebagaimana dinyatakan pada jawaban sebelumnya):

$data = json_decode(file_get_contents('php://input'));
// (then process it and build the page source)
Luca Reghellin
sumber
1
Terlalu banyak informasi yang tidak berguna .. Apa yang dilakukan kode pertama? Cuplikan kedua adalah jawabannya ..
Fipsi
@ Lipsi, (dan untuk semua downvoters) jawaban saya hanya, dan cukup jelas, ringkasan dari yang lain. Dan, seperti yang saya tulis, use case (mpdf). Pada saat penulisan, saya akan MENCINTAI untuk melihat jawaban seperti ini, ketika saya mencoba mencari cara. Dan potongan kedua saya tentu BUKAN jawabannya, karena untuk menerima data json, data harus juga dikirim dengan benar, dan tidak hanya ada lebih banyak cara untuk mengirim, tetapi sering kali cara, adalah masalah sebenarnya. Dalam hal ini, fokusnya bukan json_decode, melainkan bagaimana cara mendapatkan sesuatu dengan benar file_get_contents('php://input').
Luca Reghellin
2
Saya tidak mengundurkan diri dan saya mengerti maksud Anda .. Tetapi pertanyaannya adalah 'Terima JSON' dan bukan 'Kirim JSON'. Cukup jelas dari pertanyaan bahwa OP memiliki masalah dalam menerima dan tidak benar-benar tertarik untuk mengirim
Fipsi