Nhận JSON POST bằng PHP


292

Tôi đang cố gắng nhận JSON POST trên trang web giao diện thanh toán, nhưng tôi không thể giải mã nó.

Khi tôi in:

echo $_POST;

Tôi có:

Array

Tôi không nhận được gì khi tôi thử điều này:

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

Tôi không nhận được gì khi tôi thử điều này:

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

Tôi nhận được NULL khi tôi thử điều này:

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

Khi tôi làm:

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

Tôi có:

NULL

Định dạng JSON là (theo tài liệu trang web thanh toán):

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

Nhật ký trang web thanh toán cho biết mọi thứ đều ổn. Có vấn đề gì vậy?


4
var_dump($_POST)nói gì Có phải là một mảng trống?
Sergiu Paraschiv

3
$ _POST có từ điển yêu cầu bài viết tách biệt "&". $ _POST cho json sẽ DEFINITELY không hoạt động. Bạn có thể in file_get_contents ('php: // input') không? Ngoài ra, đó là var_dump ($ data-> hoạt động); hoặc var_dump ($ data-> operaci); ?
Akshaya Shanbhogue

4
JSON là văn bản, tại sao nó không thể truy cập được trong POST? Miễn là dịch vụ thanh toán gửi tin nhắn văn bản đó đến điểm cuối PHP của anh ta thì anh ta sẽ có thể làm được json_decode. Nhưng có lẽ dịch vụ gửi dữ liệu trong cơ thể yêu cầu , đó là một câu chuyện khác và vâng, file_get_contents('php://input')nên hoạt động sau đó.
Sergiu Paraschiv

1
Nếu vậy thì điều này đã được thảo luận ở đây: stackoverflow.com/questions/8945879/
Kẻ

3
$ _POST: Một mảng các biến kết hợp được truyền cho tập lệnh hiện tại thông qua phương thức POST HTTP khi sử dụng application / x-www-form-urlencoding hoặc Multipart / form-data làm HTTP Content-Type trong yêu cầu. Không phải khi sử dụng ứng dụng / json.
Cristian Sepulveda

Câu trả lời:


476

Thử;

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

Từ json và mã của bạn, có vẻ như bạn đã đánh vần chính xác thao tác từ trên đầu của bạn, nhưng nó không nằm trong json.

BIÊN TẬP

Có lẽ cũng đáng để thử lặp lại chuỗi json từ đầu vào php: //.

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

2
Xin chào Trong cả hai trường hợp, tôi không nhận được gì trên màn hình
Pablo Ramirez

6
Đối với những gì nó có giá trị, operacion là chính tả (cho hoặc lấy một dấu) trong tiếng Tây Ban Nha.
Patrick

11
Quan điểm của ông là ông đã không đánh vần chính xác ở cả hai nơi, hoặc là operaci hoặc hoạt động ở cả hai vị trí.
msj121

2
Trước PHP 5.6, việc lấy nội dung của php: // chỉ có thể được thực hiện một lần. Mã hoặc khung của bạn đã mở nó ở đâu đó trước đây?
aljo f

90

Nếu bạn đã có các tham số được đặt như $ _POST ['eg'] chẳng hạn và bạn không muốn thay đổi nó, chỉ cần thực hiện như sau:

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

Điều này sẽ giúp bạn tiết kiệm rắc rối khi thay đổi tất cả $ _POST sang thứ khác và cho phép bạn vẫn thực hiện các yêu cầu bài đăng bình thường nếu bạn muốn loại bỏ dòng này.


1
Cảm ơn ngài. Điều này hoạt động trong trường hợp của tôi khi tôi đang đăng json từ Android lên PHP!
vanurag

Cảm ơn bạn, nó đã làm việc trong trường hợp của tôi. Tôi đã gán dữ liệu $ _POST cho biến $ request, bây giờ tôi chỉ gán cho biến đó nội dung của php: // input.
Nhà tài trợ

Điều này chỉ làm cho ngày của tôi dễ dàng hơn nhiều. Cảm ơn.
Tyler Mammone

47

Điều đáng nói là nếu bạn sử dụng json_decode(file_get_contents("php://input"))(như những người khác đã đề cập), điều này sẽ thất bại nếu chuỗi không phải là JSON hợp lệ.

Điều này có thể được giải quyết đơn giản bằng cách kiểm tra trước xem JSON có hợp lệ không. I E

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

Chỉnh sửa: Lưu ý rằng loại bỏ strlen($json_params)trên có thể dẫn đến sai sót tinh tế, như json_last_error()không không thay đổi khi nullhoặc một chuỗi trống được thông qua, như thể hiện ở đây: http://ideone.com/va3u8U


2
Nếu ai đó đang mong đợi một lượng dữ liệu khá lớn trong đầu vào và / hoặc khối lượng yêu cầu cao, họ có thể muốn mở rộng chức năng để tùy ý đưa vào một tham chiếu biến được cung cấp với kết quả của json_decode, do đó việc phân tích cú pháp không cần được thực hiện hai lần trên đầu vào được hình thành tốt.
ngất xỉu

4
Thực hiện theo cách này, bạn thực sự giải mã json hai lần. Đó là đắt tiền. Với giải mã đầu tiên, bạn có thể lưu ngay giá trị được giải mã, thực hiện kiểm tra đó sau đó (json_last_error () == JSON_ERROR_NONE) và sau đó tiến hành xử lý nếu tất cả đều ổn [nếu không]
kakoma 26/03/19

@kakoma, chắc chắn nhất! Điều này đã được viết với sự đơn giản trong tâm trí. Đối với mục đích giáo dục, sự đơn giản thường quan trọng hơn hiệu quả. :)
XtraSimplility

1
Thật. Đối với mục đích giáo dục. Cảm ơn bạn đã làm rõ @XtraSimplicity Ha, nó thậm chí còn có tên của bạn :-)
kakoma

37

Sử dụng $HTTP_RAW_POST_DATAthay vì $_POST.

Nó sẽ cung cấp cho bạn dữ liệu POST như hiện tại.

Bạn sẽ có thể giải mã nó bằng cách sử dụng json_decode()sau.


45
Vì $ HTTP_RAW_POST_DATA hiện không được khấu hao nên bạn có thể sử dụng theo cách này để đọc JSON POST$json = file_get_contents('php://input'); $obj = json_decode($json);
Bikal Basnet

2
Đối với tôi câu trả lời chung này [sử dụng $ json = file_get_contents ('php: // input'); ] Tôi đã thấy không hoạt động khi JSON được gửi với hầu hết các "ký tự chứa" bên ngoài là []. Câu trả lời này ở đây với RAW_POST_DATA đã giúp tôi. Và vẫn ổn với ngăn xếp PHP hiện tại của tôi. Tôi đã bị mắc kẹt trong một thời gian .. cảm ơn rất nhiều cho giải pháp này!
Gene Bo

Điều này vẫn còn khá hiện tại, đối với webhook GitLab (ví dụ), bạn vẫn phải sử dụng $HTTP_RAW_POST_DATA.
developius

Tôi đã tìm kiếm và tìm kiếm một giải pháp và Bikel Basnet của bạn đã làm việc cho tôi. Cảm ơn!
Xe tay ga

điều này đã giúp tôi tiết kiệm được 3 ngày để tìm cách bắt các biến POST từ một httpClient của Angular 2 gửi yêu cầu với loại Content-Type: application / json
Frederick G. Sandalo 18/12/17


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

Điều này làm việc cho tôi.


-5

Tôi muốn đăng một câu trả lời cũng sử dụng curl để lấy nội dung và mpdf để lưu kết quả vào pdf, để bạn có được tất cả các bước của trường hợp sử dụng chính. Đó chỉ là mã thô (để phù hợp với nhu cầu của bạn), nhưng nó hoạt động.

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

Trong $ mysrcfile tôi sẽ đọc dữ liệu json như thế này (như đã nêu trong các câu trả lời trước):

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

1
Quá nhiều thông tin vô dụng .. Mã đầu tiên làm gì? Đoạn mã thứ hai là câu trả lời tho ..
Fipsi 20/07/19

@Fipsi, (và cho tất cả những người downvoters) câu trả lời của tôi là duy nhất, và rõ ràng là một bản tóm tắt của những người khác. Và, như tôi đã viết, một trường hợp sử dụng (mpdf). Tại thời điểm viết, tôi sẽ YÊU THÍCH để xem một câu trả lời như thế này, khi tôi đang cố gắng tìm ra cách để làm. Và đoạn mã thứ hai của tôi chắc chắn KHÔNG phải là câu trả lời, vì để nhận được dữ liệu json, dữ liệu cũng phải được gửi đúng cách và không chỉ có nhiều cách để gửi, mà thường là cách chính xác, là vấn đề thực sự. Trong trường hợp này, trọng tâm không phải là json_decode, thay vào đó, làm thế nào để lấy thứ gì đó đúng cách file_get_contents('php://input').
Luca Reghellin

2
Tôi đã không downvote và tôi hiểu ý định của bạn .. Nhưng câu hỏi là 'Nhận JSON' chứ không phải 'Gửi JSON'. Rõ ràng từ câu hỏi rằng OP có vấn đề nhận và không thực sự quan tâm đến việc gửi
Fipsi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.