1

Im trying to make a REST API with PHP and I've got a problem receiving POST data, if i send it with a form, it arrives perfectly fine. But when i try to send it with Content-Type application/json it arrives as empty array.

Here is the code that receives the data:

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

the data is sent with Boomerang REST client.

This are the HEADERS of the request:

POST /miel/api/inscripcion-tutoria HTTP/1.1
Host: localhost
Connection: keep-alive
Content-Length: 0
Origin: chrome-extension://eipdnjedkpcnlmmdfdkgfpljanehloah
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Content-Type: application/json
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate, br
Accept-Language: es-419,es;q=0.9,en;q=0.8,fr;q=0.7
Cookie: PHPSESSID=b586e11ef9d81...bd992603a; _ga=GA1.1.20...67.151250

The response is this one:

HTTP/1.1 200 OK
Date: Thu, 07 Dec 2017 15:49:46 GMT
Server: Apache/2.4.27 (Unix) PHP/7.1.7
X-Powered-By: PHP/7.1.7
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Pragma: no-cache
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8

Notice that Content-Length is 0, and when y execute the var_dump the data is completely empty.

I've also tried with this:

die(var_dump($_POST));

That last example only works when I send the data with a FORM like

<form action=http://localhost/miel/api/inscripcion-tutoria method=post >

In case of the form the content type is

Content-Type: application/x-www-form-urlencoded

Content length in the response headers are the same.

But if I change the content type in the boomerang REST client and put it like the one sent in the form it doesn't work neither.

I tried with the variable $HTTP_RAW_POST_DATA and the var_dump returned NULL.

Any clue on the solution would be very appreciated! Thank you!

lnogue
  • 64
  • 1
  • 7
  • Why are you using `true` for the parameter `use_include_path` in `file_get_contents`? Maybe this post helps you: https://stackoverflow.com/questions/8945879/how-to-get-body-of-a-post-in-php – dbrekelmans Dec 07 '17 at 16:12
  • 1
    @dbrekelmans think the true is on the `json_decode` – Nigel Ren Dec 07 '17 at 16:19
  • You are diagnosing several things at the same time and you have no way to know which one is failing (though it's surprising that var_dump() does not produce any output, not even `NULL`). Why don't you test `file_get_contents()` and `json_decode()` separately? – Álvaro González Dec 07 '17 at 16:30
  • Oh sorry i forgot it, it returns NULL sometimes, and with the following lines it returns ` string(0) "" ` `$entityBody = file_get_contents('php://input'); var_dump($entityBody);die;` – lnogue Dec 07 '17 at 16:58
  • Then it's clearly what you said in the question title, though you said empty *array* (I've fixed the title). In any case, the request headers include `Content-Length: 0`. Are you positively sure data is being sent in the first place? – Álvaro González Dec 07 '17 at 17:16
  • Yes im sure, data appears on the query string parameters of the request, and for some reason that I dont understand `Content-Length: 0` appears also in the `Content-Type: application/x-www-form-urlencoded` form request which works perfect. I just tried with the variable `$HTTP_RAW_POST_DATA` and the var_dump returned NULL. – lnogue Dec 07 '17 at 18:01
  • Query string? Then you aren't sending data in the request **body**. – Álvaro González Dec 09 '17 at 10:26

2 Answers2

2

I've finally found the solution to the problem. It was very simple and a matter of inexperience.

When you send a request with POSTMAN or Boomerang or any other REST client, the data must be on the body of the request.

I was using the empty fields of the "PARAMS" given by the client, but those are meant to add items to the URL, not to make a data structure for the body.

lnogue
  • 64
  • 1
  • 7
1

If you want to fetch your data using:

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

In POSTMAN Rest Client, Select "Body" which gives you options to add parameters to Request Body.

Select Raw and paste your JSON.

Make sure the Content-Type Header of your request is set to "application/json"

request body pass json data

Hope this helps.

talha2k
  • 24,937
  • 4
  • 62
  • 81