Отримати JSON POST за допомогою PHP


291

Я намагаюся отримати POST JSON на веб-сайті платіжного інтерфейсу, але не можу його розшифрувати.

Коли я друкую:

echo $_POST;

Я отримав:

Array

Я нічого не отримую, коли пробую це:

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

Я нічого не отримую, коли пробую це:

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

Я отримую NULL, коли я пробую це:

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

Коли я роблю:

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

Я отримав:

NULL

Формат JSON (відповідно до документації на платіжний сайт):

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

Журнал платежних сайтів говорить, що все в порядку. В чому проблема?


4
Що var_dump($_POST)говорить? Це порожній масив?
Сергій Паращів

3
$ _POST має словник "&" розділених запитів на публікацію. $ _POST для json ВИЗНАЧЕНО не працюватиме. Чи можете ви надрукувати file_get_contents ('php: // input')? Також це var_dump ($ data-> операція); або var_dump ($ data-> operacion); ?
Akshaya Shanbhogue

4
JSON - це текст, чому б він не був доступний в POST? Поки платіжна служба розміщує цей текст у кінцевій точці PHP, тоді він повинен мати змогу json_decode. Але, можливо, сервіс надсилає дані в орган запиту , це вже інша історія, і так, file_get_contents('php://input')слід працювати тоді.
Сергій Паращів

1
Якщо так, то це обговорювалося тут: stackoverflow.com/questions/8945879/…
Сергій Паращів

3
$ _POST: асоціативний масив змінних, переданих у поточний сценарій за допомогою методу HTTP POST при використанні data / x-www-form-urlencoded або multipart / form-data як тип вмісту HTTP у запиті. Не під час використання application / json.
Крістіан Сепульведа

Відповіді:


476

Спробуйте;

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

З вашого json та вашого коду, схоже, ви правильно написали слово операцію на своєму кінці, але це не в json.

EDIT

Можливо, варто також спробувати відлучити рядок json з php: // input.

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

2
Привіт В обох випадках я нічого не отримую на екрані
Пабло Рамірес

6
Оскільки це варте, operacion - це написання іспанською мовою (дати або наголосити).
Патрік

11
Його думка полягала в тому, що він не написав це правильно в обох місцях, ні в операції, ні в обох місцях.
msj121

2
Перед PHP 5.6 отримання вмісту php: // можна було зробити лише один раз. Чи могли ваш код або фреймворк відкрити його десь раніше?
aljo f

90

Якщо у вас вже є параметри, наприклад, $ _POST ['eg'], наприклад, і ви не хочете їх змінювати, просто зробіть це так:

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

Це позбавить вас від клопоту змінити $ _POST на щось інше і дозволить вам все-таки робити звичайні поштові запити, якщо ви хочете вивести цю лінію.


1
Дякую вам сер. У моєму випадку це спрацювало, коли я роблю json-повідомлення з Android на PHP!
ванураг

Дякую, це спрацювало в моєму випадку. Я призначав дані $ _POST змінної $ request, тепер я просто призначив цій змінній вміст php: // input.
Funder

Це просто полегшило мені день. Дякую.
Маймон Тайлера

46

Варто відзначити, що якщо ви використовуєте json_decode(file_get_contents("php://input"))(як уже згадувалося), це буде помилкою , якщо рядок НЕ діє в форматі JSON.

Це можна вирішити просто, попередньо перевіривши, чи дійсний JSON. тобто

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

Редагувати: Зверніть увагу, що видалення strlen($json_params)вище може призвести до тонких помилок, оскільки json_last_error()це не змінюється при nullпередачі чи порожній рядку, як показано тут: http://ideone.com/va3u8U


2
Якщо хтось очікує досить великого обсягу даних на вході та / або великому обсязі запитів, він може захотіти розширити функцію для додаткового заповнення наданої змінної посилання з результатом json_decode, так що для аналізу не потрібно виконується двічі на добре сформованому вході.
фансигнал

4
Зроблено таким чином, ви фактично декодуєте json двічі. Це дорого. За допомогою першого декодування ви можете негайно зберегти розшифроване значення, зробіть це після цього (json_last_error () == JSON_ERROR_NONE), а потім продовжуйте обробку, якщо все добре [не вдається інакше]
kakoma

@kakoma, безумовно! Це було написано з простотою на увазі. Для цілей освіти простота часто важливіша за ефективність. :)
XtraSimplicity

1
Правда. З метою освіти. Дякую за роз’яснення @XtraSimplicity Ha, воно навіть у вашому імені :-)
kakoma

37

Використовуйте $HTTP_RAW_POST_DATAзамість $_POST.

Це дасть вам дані POST, як є.

Ви зможете розшифрувати його за допомогою json_decode()пізніше.


45
Оскільки $ HTTP_RAW_POST_DATA амортизується, ви можете таким чином прочитати JSON POST$json = file_get_contents('php://input'); $obj = json_decode($json);
Bikal Basnet

2
Для мене ця поширена відповідь [використовуйте $ json = file_get_contents ('php: // input'); ] Я бачив, що не працює, коли JSON надсилається з найбільш зовнішніми "контейнерними символами" як []. Ця відповідь тут із RAW_POST_DATA зробила для мене трюк. І це добре з моїм поточним стеком PHP. Я застряг на деякий час .. дуже дякую за це рішення!
Джин Бо

Це все ще досить актуально, для веб-куточків GitLab (наприклад) ви все ще повинні користуватися $HTTP_RAW_POST_DATA.
developius

Я шукав і шукав рішення, і Bikel Basnet ваша працювала на мене. Дякую!
Скутер

це врятувало мої 3 дні, розглядаючи способи вилучення змінних POST від HttpClient of Angular 2, надсилаючи запит типу Content-Type: application / json
Frederick G. Sandalo



-5

Я хотів би опублікувати відповідь, яка також використовує curl для отримання вмісту, і mpdf для збереження результатів у pdf, щоб ви отримали всі етапи випадкового використання. Це лише необроблений код (щоб він був адаптований до ваших потреб), але він працює.

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

У $ mysrcfile я прочитаю такі дані json (як зазначено у попередніх відповідях):

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

1
Занадто багато непотрібної інформації .. Що робить перший код? Другий фрагмент є відповіддю тхо ..
Fipsi

@Fipsi, (і для всіх поточних людей) моя відповідь є лише, і цілком очевидно, складом інших. І, як я писав, випадок використання (mpdf). На момент написання я хотіла б бачити таку відповідь, коли я намагалася зрозуміти, як це зробити. І мій другий фрагмент, безумовно, НЕ відповідь, оскільки для отримання даних json, дані також повинні бути належним чином відправлені, і не тільки є більше способів надіслати, але часто це шлях - це саме справжня проблема. У цьому випадку фокус не є json_decode, а замість того, як правильно щось отримати file_get_contents('php://input').
Лука Регеллін

2
Я не заявив, і я розумію ваш намір. Але питання "Отримати JSON", а не "Надіслати JSON". З питання досить зрозуміло, що в ОП є проблеми з отриманням і не дуже зацікавлені в надсиланні
Fipsi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.