0

When I POST data to my server using a regular old form submit I can pull that data from the $_POST variable, but when POSTing JSON data via AJAX I need to access it via file_get_contents('php://input'). Why is that? In both cases I am using the POST method, are there some explicit headers I should be setting on my AJAX call? I have only ever come up against this problem on the current development server and have never had to use file_get_contents('php://input') before. Is there a server setting somewhere? Can I change this behaviour with a .htaccess?

Abraham Brookes
  • 1,720
  • 1
  • 17
  • 32
  • 2
    There may be some useful info for you here, even if you aren't using angular: https://stackoverflow.com/questions/15485354/angular-http-post-to-php-and-undefined – Don't Panic Apr 03 '18 at 22:55
  • you can tweak some headers to make it populate $_POST, but cant remember which ones. (sorry not very helpfull) –  Apr 03 '18 at 23:09
  • 1
    Perhaps the content type for the POST request was something other than `application/x-www-form-urlencoded` and `multipart/form-data`. May be it was `application/json`. PHP will not populate `$_POST` then. – Salman A Apr 19 '18 at 03:48

2 Answers2

1

Add this to the top of your .php file:

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

so that the contents will be property decoded and available. After that, you can access individual keys as usual.

Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • 2
    I've been doing that but I want to know _why_. And why I haven't had to do it before. – Abraham Brookes Apr 03 '18 at 22:56
  • @AbrahamBrookes My understanding is that it is simply because the payload is JSON and to properly be able to create the POST array, the JSON must be decoded. – Scott Marcus Apr 03 '18 at 23:24
0

So as far as I have been able to find out, this has something to do with the way the data is received by the server - PHP can't natively parse JSON. Sending plain old JSON objects from Javascript to PHP will result in PHP not knowing what to do with the datatype, and thus it won't be able to prepopulate the appropriate global variables.

In order to get around it I added a check to my ajax wrapper function that intercepts the JSON, encodes is as a FormData object and shoots that off to the server instead.

Abraham Brookes
  • 1,720
  • 1
  • 17
  • 32