A few days ago I've been working a project which, as many other projects out there today, communicates with some external APIs. At some point, in order to perform some tests, I had to write an API endpoint within my project itself to fake the actual external API. I need to mention that the external API was expecting application/json
content type, so basically the curl
setup looked like this:
<?php
//...
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch, CURLOPT_VERBOSE, true );
curl_setopt( $ch, CURLOPT_HEADER, true );
curl_setopt( $ch, CURLOPT_TIMEOUT, $this->timeout_limit );
curl_setopt( $ch, CURLOPT_ENCODING, '' );
curl_setopt( $ch, CURLOPT_MAXREDIRS, 10 );
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'POST' );
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode( $data ) );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json'
) );
// ...
The issue was that when I've been trying to catch the POST data and use it, I was getting null
as a value for both $_POST
or $_REQUEST
, and I couldn't understand why π€. Apparently (and maybe many of you already knew that), if the data is sent as multipart/form-data
or application/x-www-form-urlencoded
then yes, you can use PHP globals $_POST
or $_REQUEST
to catch and use that data. But, if the data is sent as application/json
, then prior to PHP 5.6 you could've use $HTTP_RAW_POST_DATA to grab the raw POST data, or (and based on PHP docs this is the preferable way to do it) use the php://input - a read-only stream that allows you to read raw data from the request body.
So, as a result I ended up grabbing the POST data like this:
<?php
// receive the JSON Post data
$data = json_decode( file_get_contents( 'php://input' ), true );
Big credits to these stackoverflow discussions:
https://stackoverflow.com/questions/2731297/file-get-contentsphp-input-or-http-raw-post-data-which-one-is-better-to
https://stackoverflow.com/questions/813487/how-to-post-json-to-php-with-curl/813512
Happy coding everyone! π» π€ π
Top comments (6)
Just In Case, If anyone need this
Hello! I am trying to send a json in the following way
$factura ->acciones = array('enviar_xml_firmado' => false );
$ch = curl_init($url);
$jsonDataEncoded = json_encode($factura);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json' , $authorization ));
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS,$jsonDataEncoded);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result);
but I get the error $HTTP_RAW_POST_DATA de php 5.6, in which part or in what form should I go
$data = json_decode( file_get_contents( 'php://input' ), true );
so that it works well?
Hi there, were you able to solve the issue?
Thanks Vasile, this really helped me. Working with a very old framework here that still uses PHP 5.6 and had this exact issue of $_POST being empty everytime I sent JSON.
Nice! Any headers etc to put in the receiving end in order to accept only post/json?
You shouldn't need to. You only set the
Content-Type: application/json
when sending out the request.