Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
632 views
in Technique[技术] by (71.8m points)

javascript - file_get_contents('php://input'); with application/x-www-form-urlencoded;

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

56.8k users

...