3

I am trying to send a tiny bit of data from javascript using XMLHttpRequest and a Json string to a PHP script to process it and return some response in the form of a Json string again, but I've ran into tons of issues and different methods that just won't work together properly, here's what has worked so far:

Client

json_string = '{"foo":"1","bar":"2"}';

var r = new XMLHttpRequest();
r.open('post', 'script.php', true);
r.setRequestHeader('Content-type','application/json; charset=utf-8');
r.setRequestHeader('Content-length', json_string.length);
r.setRequestHeader('Connection', 'close');
r.onload = function () {
    console.log(this.responseText);
};
r.send(json_string);

Server

$json = file_get_contents('php://input');

echo $json;

It can't get simpler than this, however I'm getting this warning:

[09-Jan-2015 15:50:03 America/Mexico_City] 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. in Unknown on line 0

[09-Jan-2015 15:50:03 America/Mexico_City] PHP Warning: Cannot modify header information - headers already sent in Unknown on line 0

And of course the response text looks like this:

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. in Unknown on line 0

Warning: Cannot modify header information - headers already sent in Unknown on line 0
{"foo":"1","bar":"2"}"

What am I doing wrong? Why does PHP complain about already sent headers?

I'm using PHP 5.6.

16
  • 4
    I'd suggest you start using jquery to do ajax. I've already forgotten how to do it the manual way, and I'm glad I did. Commented Jan 9, 2015 at 22:10
  • 2
    The error you're getting, however, is because of $json = file_get_contents('php://input'); You can't use php://input anymore. You have to put your json in a request parameter and read that parameter with $_POST. Commented Jan 9, 2015 at 22:12
  • 3
    @developerwjk So much misinformation and weak advice. There are a million and one reasons why someone might want to use native JS. You can't use php://input anymore - explain what that means. I used it today.\ Commented Jan 9, 2015 at 22:14
  • 3
    @developerwjk: php://input is the correct method to use. Commented Jan 9, 2015 at 22:15
  • 2
    @arielnmz: In that case, you'd need to ask your hosting provider to update the php.ini file. PHP is set up incorrectly and it should be their job to fix it! If they don't fix it, I'd suggest finding another hosting service. Commented Jan 9, 2015 at 22:23

2 Answers 2

6

You need to edit your php.ini file and set always_populate_raw_post_data = -1.

Your code is working just fine. $json = file_get_contents('php://input'); is correct.

You are just getting a warning because your PHP was updated and you need to update the php.ini file for that new version.

More info here: https://www.bram.us/2014/10/26/php-5-6-automatically-populating-http_raw_post_data-is-deprecated-and-will-be-removed-in-a-future-version/

Sign up to request clarification or add additional context in comments.

6 Comments

Okay, so I understand that the warning is because the default behavior was to automatically populate the data, and now in 5.6 it's necessary to explicitly indicate that PHP should always populate raw data and what's deprecated is automatically assuming you want to always populate raw data, am I right?
@arielnmz: The default prior to PHP 5.6 was to populate the raw data when it got a MIME type it did not recognize via POST. In PHP 5.6+, populating raw data is deprecated. It should never be done. Setting the ini value to -1 tells PHP to never to do so. The ini values are 1: always, 0: only when MIME is not recognized, -1: never.
So the warning comes up because I don't have such setting set, right?
@arielnmz: Correct. The default was to set always_populate_raw_post_data = 0. PHP 5.6 wants it to be set to -1, so it throws a warning about that.
Ok, so, summing things up: the warning is because setting always_populate_raw_post_data to 0 (or don't explicitly setting it) is deprecated, but receiving input via php://input is still valid, right?
|
1

I looked at some of my old code that does do Ajax without Jquery. To send Json in a POST parameter is not that different from what you're doing already.

You really only need to change the headers you are setting, and give it a parameter name:

json_string = '{"foo":"1","bar":"2"}';

var r = new XMLHttpRequest();
r.open('post', 'script.php', true);
r.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
r.onload = function () {
    console.log(this.responseText);
};
r.send('json='+encodeURIComponent(json_string));

And then, of course in PHP:

$_POST['json']

Edit: Added encodeURIComponent().

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.