รับ JSON POST ด้วย PHP


292

ฉันกำลังพยายามรับ JSON POST บนเว็บไซต์อินเทอร์เฟซการชำระเงิน แต่ฉันไม่สามารถถอดรหัสได้

เมื่อฉันพิมพ์:

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)พูด? มันเป็นอาร์เรย์ที่ว่างเปล่า?
Sergiu Paraschiv

3
$ _POST มีพจนานุกรมคำว่า "&" คั่นคำขอโพสต์ $ _POST สำหรับ json จะไม่สามารถใช้งานได้อย่างแน่นอน คุณสามารถพิมพ์ file_get_contents ('php: // input') ได้หรือไม่? นอกจากนี้ยังเป็น var_dump ($ data-> operation); หรือ var_dump ($ data-> operacion); ?
Akshaya Shanbhogue

4
JSON เป็นข้อความทำไมถึงไม่สามารถเข้าถึงได้ใน POST ตราบใดที่โพสต์บริการการชำระเงินที่ข้อความไปยังปลายทาง PHP ของเขาแล้วเขาควรจะได้json_decodeมัน แต่บริการอาจส่งข้อมูลไปยังเนื้อความที่ร้องขอซึ่งเป็นเรื่องที่แตกต่างและใช่แล้วfile_get_contents('php://input')ควรใช้งานได้
Sergiu Paraschiv

1
ถ้าเป็นเช่นนั้นจะมีการพูดถึงที่นี่: stackoverflow.com/questions/8945879/…
Sergiu Paraschiv

3
$ _POST: อาร์เรย์ที่เชื่อมโยงของตัวแปรที่ส่งผ่านไปยังสคริปต์ปัจจุบันผ่านวิธี HTTP POST เมื่อใช้ application / x-www-form-urlencoded หรือ multipart / form-data เป็น HTTP Content-Type ในคำขอ ไม่เมื่อใช้แอปพลิเคชัน / json
Cristian Sepulveda

คำตอบ:


477

ลอง;

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

จาก json และรหัสของคุณดูเหมือนว่าคุณสะกดคำว่าการดำเนินการอย่างถูกต้องในตอนท้ายของคุณ แต่มันไม่ได้อยู่ใน json

แก้ไข

อาจคุ้มค่ากับการพยายามที่จะสะท้อนสตริง json จาก php: // input

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

2
สวัสดีทั้งสองกรณีฉันไม่ได้อะไรเลยบนหน้าจอ
Pablo Ramirez

6
สำหรับสิ่งที่คุ้มค่าโอเปอเรโตคือการสะกด (ให้หรือใช้สำเนียง) ในภาษาสเปน
Patrick

11
ประเด็นของเขาคือเขาไม่ได้สะกดอย่างถูกต้องในทั้งสองแห่งไม่ว่าจะเป็นโอเปร่าหรือการผ่าตัดในทั้งสองแห่ง
msj121

2
ก่อน PHP 5.6 การรับเนื้อหาของ php: // อินพุตสามารถทำได้เพียงครั้งเดียว รหัสหรือกรอบงานของคุณเคยเปิดขึ้นมาก่อนหน้านี้ไหม?
aljo f

90

หากคุณตั้งค่าพารามิเตอร์เป็น $ _POST ['เช่น'] ไว้แล้วและคุณไม่ต้องการที่จะเปลี่ยนแปลงเพียงทำแบบนี้:

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

วิธีนี้จะช่วยให้คุณไม่ต้องยุ่งยากกับการเปลี่ยน $ _POST ทั้งหมดเป็นอย่างอื่นและช่วยให้คุณสามารถส่งคำขอโพสต์ปกติได้หากคุณต้องการนำบรรทัดนี้ออก


1
ขอบคุณครับ สิ่งนี้ทำงานในกรณีของฉันเนื่องจากฉันกำลังโพสต์ json จาก Android ไปยัง PHP!
vanurag

ขอบคุณมันใช้งานได้ในกรณีของฉัน ฉันกำหนดข้อมูล $ _POST ให้กับตัวแปร $ request ตอนนี้ฉันเพิ่งกำหนดให้ตัวแปรนั้นคือเนื้อหาของ php: // input
Funder

นี่ทำให้วันของฉันง่ายขึ้นมาก ขอบคุณ
Tyler Mammone

47

เป็นค่าชี้ให้เห็นว่าถ้าคุณใช้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 เพื่อให้การแยกวิเคราะห์ไม่จำเป็นต้อง จะดำเนินการสองครั้งในการป้อนข้อมูลที่ดีขึ้น
faintsignal

4
ทำแบบนี้คุณจะถอดรหัส json สองครั้ง นั่นแพงมาก ด้วยการถอดรหัสครั้งแรกคุณสามารถบันทึกค่าที่ถอดรหัสได้ทันทีทำการตรวจสอบหลังจากนั้น (json_last_error () == JSON_ERROR_NONE) จากนั้นดำเนินการประมวลผลหากทั้งหมดเป็นอย่างดี [ล้มเหลวอย่างอื่น]
kakoma

@kakoma แน่นอนที่สุด! มันเขียนด้วยความเรียบง่ายในใจ เพื่อวัตถุประสงค์ด้านการศึกษาความเรียบง่ายมักจะสำคัญกว่าประสิทธิภาพ :)
XtraSimplicity

1
จริง เพื่อการศึกษา ขอบคุณสำหรับการชี้แจง @XtraSimplicity ฮ่ามันยังอยู่ในชื่อของคุณ :-)
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 สแต็คปัจจุบันของฉัน ฉันติดอยู่พักหนึ่งแล้วขอบคุณมากสำหรับวิธีนี้!
Gene Bo

นี้ยังคงเป็นปัจจุบันสวยสำหรับGitLab webhooks (ตัวอย่าง), $HTTP_RAW_POST_DATAคุณยังคงต้องใช้
developius

ฉันค้นหาและค้นหาวิธีแก้ปัญหาและ Bikel Basnet คุณทำงานให้ฉัน ขอบคุณ!
สกูตเตอร์

สิ่งนี้ช่วยให้ 3 วันของฉันดูวิธีจับตัวแปร POST จาก HttpClient of Angular 2 ส่งคำขอด้วยประเภทเนื้อหา - ประเภท: application / json
Frederick G. Sandalo

12

อ่านเอกสาร:

โดยทั่วไปแล้ว php: // ควรใช้แทน $ HTTP_RAW_POST_DATA

เช่นเดียวกับในคู่มือ PHP


4
คำเตือนคุณสมบัตินี้เลิกใช้งานใน PHP 5.6.0 และถูกลบออกเป็น PHP 7.0.0 => php.net/manual/en/reserved.variables.httprawpostdata.php
โปรโมชั่น


-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')ก็แทนวิธีการอย่างถูกต้องจะได้รับบางสิ่งบางอย่างจาก
Luca Reghellin

2
ฉันไม่ได้ลงคะแนนและเข้าใจความตั้งใจของคุณ .. แต่คำถามคือ 'รับ JSON' และไม่ใช่ 'ส่ง JSON' มันค่อนข้างชัดเจนจากคำถามที่ว่า OP มีปัญหาในการรับและไม่สนใจที่จะส่งจริงๆ
Fipsi
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.