I've read a few questions about the subject here on but couldn't find the answer I'm looking for. I'm doing some $.post with jQuery to a PHP5.6 server.
$.post('/', {a:100, b:'test'}, function(data){
}, 'json');
The encoding from the console is
Content-Type application/x-www-form-urlencoded; charset=UTF-8
If I try to read the POST data with a regular $_POST, PHP5.6 alerts me
PHP Deprecated: Automatically populating $HTTP_RAW_POST_DATA is deprecated and will be removed in a future version. To avoid this warning set 'always_populate_raw_post_data' to '-1' in php.ini and use the php://input stream instead
So then I've tried the suggestion, added always_populate_raw_post_data = -1 in php.ini and
json_decode(file_get_contents("php://input"));
PHP5.6 alerts me that it is invalid
PHP Warning: First parameter must either be an object or the name of an existing class
So I've dumped file_get_contents("php://input") and it's a string.
a=100&b="test"
So I've parsed the string and encoded then decoded
parse_str(file_get_contents("php://input"), $data);
$data = json_decode(json_encode($data));
var_dump($data);
And THEN I finally have my $data as an object and not an array, as a true JSON object.
I've resorted to keep on using $_POST for now... But then I'm wondering about upgrading PHP..
The question here is that, is there a straighter forward solution to this or does it mean using file_get_contents("php://input") also means doing the parsing decoding encoding shenanigans?
Edit: so it appears this doesn't work either on multi levels json's. Consider the following:
{"a":100, "b":{"c":"test"}}
As sent in Ajax/Post
{a:100, b:{c:"test"}}
Doing
parse_str(file_get_contents("php://input"), $post);
var_dump($post);
Will output
array(2) {
["a"]=>string(8) "100"
["b"]=>string(16) "{"c":"test"}"
}
Or doing (as suggested)
parse_str(file_get_contents("php://input"), $post);
$post= (object)$post;
Will output
object(stdClass)#11 (2) {
["a"]=>string(8) "100"
["b"]=>string(16) "{"c":"test"}"
}
How do I transform file_get_contents("php://input") into a true object with the same "architecture" without using a recursive function?
Edit2 : My mistake, the suggested worked, I got side tracked in the comments with JSON.stringify which caused the error. Bottom line: it works with either json_decode(json_encode($post)) or $post=(object)$post;
To recap, using jQuery $.post :
$.post('/', {a:100, b:{c:'test'}}, function(data){
}, 'json');
parse_str(file_get_contents("php://input"), $data);
$data = json_decode(json_encode($data));
or
parse_str(file_get_contents("php://input"), $data);
$data= (object)$data;
No need to use JSON.stringify
In order to send raw json data, you have to stop jQuery from url-encoding it:
data = {"a":"test", "b":{"c":123}};
$.ajax({
type: 'POST',
url: '...',
data: JSON.stringify(data), // I encode it myself
processData: false // please, jQuery, don't bother
});
On the php side, just read php://input
and json_decode
it:
$req = file_get_contents("php://input");
$req = json_decode($req);
Receiving serialized/urlencoded POST data in the request's POST body as you are, you've correctly transformed it into an array with parse_str()
already.
However, the step of encoding then decoding JSON in order to transform that into the object (as opposed to array) you're looking for is unnecessary. Instead, PHP will happily cast an associative array into an object of class stdClass
:
parse_str(file_get_contents("php://input"), $data);
// Cast it to an object
$data = (object)$data;
var_dump($data);
A little more information is available in the PHP documentation on type casting.
My mistake, the suggested worked, I got side tracked in the comments with JSON.stringify which caused the error. Bottom line: it works with either json_decode(json_encode($post)) or $post=(object)$post; The answer Michael gave is correct but side tracked me and I left the error in my code. JSON.stringify is only useful when posting the data from a form as I replied in the comment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With