Receive JSON POST with PHP
Asked Answered
M

14

426

I’m trying to receive a JSON POST on a payment interface website, but I can’t decode it.

When I print :

echo $_POST;

I get:

Array

I get nothing when I try this:

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

I get nothing when I try this:

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

I get NULL when I try this:

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

When I do:

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

I get:

NULL

The JSON format is (according to payment site documentation):

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

The payment site log says everything is OK. What’s the problem?

Marciamarciano answered 18/9, 2013 at 7:47 Comment(10)
What does var_dump($_POST) say? Is it an empty array?Leastwise
var_dump($_POST); what you get?Gerenuk
$_POST has the dictionary of "&" separated post requests. $_POST for json will DEFINITELY not work. Can you print file_get_contents('php://input')? Also is it var_dump($data->operation); or var_dump($data->operacion); ?Supernatant
Try <?php echo '<pre>'; print_r($_POST); echo '</pre>'; ?> What does that show?Utility
JSON is text, why wouldn't it be accessible in POST? As long as the payment service POSTs that text to his PHP endpoint then he should be able to json_decode it. But maybe the service sends data in request body, that's a different story and yes, file_get_contents('php://input') should work then.Leastwise
If so then this has been discussed here: #8946379Leastwise
Hi. Thanks everyone. When I do var_dump($_POST) I get array(0) { }. When I do echo '<pre>'; print_r($_POST); echo '</pre>'; I get Array ( ) And yes, documentation says "we will make post request sending json in request body" When I do $entityBody = file_get_contents('php://input'); var_dump($entityBody); I get string(0)Marciamarciano
Update> When I do $data = json_decode(file_get_contents('php://input'), true); var_dump($data); I get NULLMarciamarciano
$_POST: An associative array of variables passed to the current script via the HTTP POST method when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request. Not when using application/json.Impunity
@PabloRamirez Hi, may i know did you have the solution? Because i also have this issue. #18867071Bust
C
657

Try;

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

From your json and your code, it looks like you have spelled the word operation correctly on your end, but it isn't in the json.

EDIT

Maybe also worth trying to echo the json string from php://input.

echo file_get_contents('php://input');
Cabe answered 18/9, 2013 at 8:30 Comment(4)
For what it's worth, operacion is the spelling (give or take an accent) in Spanish.Burdette
His point was that he didn't spell it correctly in both places, either operacion or operation in both spots.Manservant
Before PHP 5.6, getting the contents of php://input could only be done once. Could your code or framework have opened it somewhere before?Lewandowski
Pay attention to not using single quote on json dataGalle
F
134

If you already have your parameters set like $_POST['eg'] for example and you don't wish to change it, simply do it like this:

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

This will save you the hassle of changing all $_POST to something else and allow you to still make normal post requests if you wish to take this line out.

Finer answered 15/9, 2016 at 10:7 Comment(3)
Thank you sir. This worked in my case as I am doing json posting from Android to PHP!Blackpool
Thank you, it did work in my case. I was assigning the $_POST data to a $request variable, now I just assigned to that variable the content of php://input.Martens
Hi, I have something like this in php $sql = "INSERT INTO userdetails (email, username) VALUES ('".$_POST['email']."', '".$_POST['username']."')"; if (mysqli_query($conn,$sql)) { $data = array("data" => "You Data added successfully"); echo json_encode($data); . How can I change the code here so that I can pass json and push into phpmysql database fields ?Verine
S
67

It is worth pointing out that if you use json_decode(file_get_contents("php://input")) (as others have mentioned), this will fail if the string is not valid JSON.

This can be simply resolved by first checking if the JSON is valid. 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);

Edit: Note that removing strlen($json_params) above may result in subtle errors, as json_last_error() does not change when null or a blank string is passed, as shown here: http://ideone.com/va3u8U

Stormy answered 15/6, 2016 at 23:12 Comment(5)
If someone is expecting a rather large amount of data in the input and/or a high volume of requests, they may want to extend the function to optionally populate a provided variable reference with the result of json_decode, so that the parsing does not need to be performed twice on well-formed input.Astern
Done this way, you actually decode the json twice. That's expensive. With the first decode, you can immediately save the decoded value, do that check afterwards (json_last_error() == JSON_ERROR_NONE) and then proceed with the processing if all is well [fail otherwise]Freckle
@kakoma, most definitely! This was written with simplicity in mind. For education purposes, simplicity is often more important than efficiency. :)Stormy
True. For education purposes. Thanks for the clarification @Stormy Ha, it is even in your name :-)Freckle
PHP8.3 Now has json_validate(). https://mcmap.net/q/73472/-fastest-way-to-check-if-a-string-is-json-in-php and php.watch/versions/8.3/json_validateCooee
H
37

Use $HTTP_RAW_POST_DATA instead of $_POST.

It will give you POST data as is.

You will be able to decode it using json_decode() later.

Hearthstone answered 26/3, 2014 at 13:11 Comment(6)
Since $HTTP_RAW_POST_DATA is depreciated now you can use in this way to read JSON POST $json = file_get_contents('php://input'); $obj = json_decode($json);Nard
For me this common answer [ use $json = file_get_contents('php://input'); ] I was seeing did not work when the JSON was being sent with outer most "container chars" as []. This answer here with RAW_POST_DATA did the trick for me. And is fine with my current PHP stack. I was stuck for a while .. thanks very much for this solution!Intervenient
This is still pretty current, for GitLab webhooks (for example), you still have to use $HTTP_RAW_POST_DATA.Amoy
I searched and searched for a solution and Bikel Basnet yours worked for me. Thanks!Lorenz
this saved my 3 days looking at ways to catch the POST variables from an HttpClient of Angular 2 sending a request with type Content-Type: application/jsonPupil
Warning This feature was DEPRECATED in PHP 5.6.0, and REMOVED as of PHP 7.0.0.Athey
C
16

You can use bellow like.. Post JSON like bellow

enter image description here

Get data from php project user bellow like

// takes raw data from the request 
$json = file_get_contents('php://input');
// Converts it into a PHP object 
$data = json_decode($json, true);

 echo $data['requestCode'];
 echo $data['mobileNo'];
 echo $data['password'];
Canopus answered 1/5, 2021 at 5:6 Comment(1)
This is the answer. PHP only interprets body in formData form, not JSON. The code from @enamul-haque fixes that.Litt
A
15

Read the doc:

In general, php://input should be used instead of $HTTP_RAW_POST_DATA.

as in the php Manual

Azotize answered 2/5, 2016 at 12:55 Comment(3)
Warning This feature was DEPRECATED in PHP 5.6.0, and REMOVED as of PHP 7.0.0. => php.net/manual/en/reserved.variables.httprawpostdata.phpGerm
And the link is now brokenTawnatawney
In the case of POST requests, it is preferable to use php://input instead of $HTTP_RAW_POST_DATA as it does not depend on special php.ini directives. Moreover, for those cases where $HTTP_RAW_POST_DATA is not populated by default, it is a potentially less memory intensive alternative to activating always_populate_raw_post_data. php://input is not available with enctype="multipart/form-data".Sachiko
R
12
$data = file_get_contents('php://input');
echo $data;

This worked for me.

Robison answered 17/6, 2018 at 20:4 Comment(0)
V
5

Quite late.
It seems, (OP) had already tried all the answers given to him.
Still if you (OP) were not receiving what had been passed to the ".PHP" file, error could be, incorrect URL.
Check whether you are calling the correct ".PHP" file.
(spelling mistake or capital letter in URL)
and most important
Check whether your URL has "s" (secure) after "http".
Example:

"http://yourdomain.com/read_result.php"

should be

"https://yourdomain.com/read_result.php"

or either way.
add or remove the "s" to match your URL.

Visage answered 6/12, 2020 at 10:40 Comment(0)
D
4

If all of the above answers still leads you to NULL input for POST, note that POST/JSON in a localhost setting, it could be because you are not using SSL. (provided you are HTTP with tcp/tls and not udp/quic)

PHP://input will be null on non-https and if you have a redirect in the flow, trying configuring https on your local as standard practice to avoid various issues with security/xss etc

Dewie answered 29/8, 2021 at 14:6 Comment(1)
This saved me. Was not posting to https:// if you post to http:// it doesn't work anymore with PHP < 7.0Gove
A
1

The decoding might be failing (and returning null) because of php magic quotes.

If magic quotes is turned on anything read from _POST/_REQUEST/etc. will have special characters such as "\ that are also part of JSON escaped. Trying to json_decode( this escaped string will fail. It is a deprecated feature still turned on with some hosters.

Workaround that checks if magic quotes are turned on and if so removes them:

function strip_magic_slashes($str) {
    return get_magic_quotes_gpc() ? stripslashes($str) : $str;
}

$operation = json_decode(strip_magic_slashes($_POST['operation']));
Actuate answered 15/12, 2021 at 0:22 Comment(1)
get_magic_quotes_gpc() was deprecated in PHP 7.4 and removed as of version PHP 8.0Oust
M
1

I too ran into this issue with the same results.

  1. $_POST was empty.
  2. file_get_contents('php://input') was empty
  3. Even the $_REQUEST array was empty.

Background:

I was posting to an index.php file within an ajax/post directory, i.e. ajax/post/index.php

The url I was using was https://example.com/ajax/post.

The Problem:

The $_POST array was empty because the server used a 301 redirect to move my request from https://example.com/ajax/post to https://example.com/ajax/post/. Note the trailing slash. The redirect occurred, but the posted body did not come along with it.

The Solution

Try adding a trailing slash to the url you are posting to.

Instead of https://example.com/ajax/post try using https://example.com/ajax/post/

Mammalian answered 4/4, 2023 at 22:21 Comment(0)
P
0

I got "null" when I tried to retrieve a posted data in PHP

{
    "product_id": "48",
    "customer_id": "2",  
    "location": "shelf",  // shelf, store <-- comments create php problems
    "damage_types":{"Pests":1, "Poke":0, "Tear":0}
     // "picture":"jhgkuignk"  <-- comments create php problems
}

You should avoid commenting JSON code even if it shows no errors

Phylis answered 8/9, 2022 at 15:16 Comment(0)
R
0

In my case docs from CKEditor stated "When the image upload process is initiated, the adapter sends a POST request ..." so i tried file_get_contents('php://input') or $_POST $_REQUEST $_GET and they were all empty. Solved with $_FILES.

Roentgenograph answered 16/4 at 14:35 Comment(0)
H
-3

I'd like to post an answer that also uses curl to get the contents, and mpdf to save the results to a pdf, so you get all the steps of a tipical use case. It's only raw code (so to be adapted to your needs), but it works.

// 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 I'll read json data like this (as stated on previous answers):

$data = json_decode(file_get_contents('php://input'));
// (then process it and build the page source)
Hopkins answered 31/7, 2018 at 9:28 Comment(3)
Too much useless information.. What does the first code do? The second snippet is the answer tho..Briolette
@Fipsi, (and to all the downvoters) my answer is only, and quite obviously, a compendium of the others. And,as I wrote, a use case (mpdf). At the time of writing, I would have LOVED to see an answer like this, when I was trying to figure out how to. And my second snippet is certainly NOT the answer, since to receive json data, the data has to be also properly sent, and not only there are more ways to send, but often the way, is exactly the real problem. In this case, the focus is not json_decode, it's instead how to properly get something from file_get_contents('php://input').Hopkins
I didn't downvote and I understand your intention.. But the question is 'Receive JSON' and not 'Send JSON'. It's pretty clear from the question that the OP has issues receiving and isn't really interested in sendingBriolette

© 2022 - 2024 — McMap. All rights reserved.