loading...

Catch and parse JSON Post data in PHP

dev_nope profile image Vasile Stefirta πŸ‡²πŸ‡© ✈️ πŸ‡ΊπŸ‡Έ Updated on ・2 min read

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! πŸ’» πŸ€“ πŸ‘

Posted on Feb 4 '18 by:

dev_nope profile

Vasile Stefirta πŸ‡²πŸ‡© ✈️ πŸ‡ΊπŸ‡Έ

@dev_nope

πŸ‘‹ Full Stack Developer πŸ’» πŸ‘‰ Husband and father πŸ‘ͺ πŸ‘‰ Electronic music and soccer lover 🎧 ⚽✌️

Discussion

markdown guide
 

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?

 
 

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.