POSTing JSON Data With PHP cURL

I got this question the other day: how to send a POST request from PHP with correctly-formatted JSON data? I referred to the slides from my web services tutorial for the answer, and I thought I'd also put it here, with a bit of explanation. After all, publishing your slides is all very well, but if you didn't see the actual tutorial, I often think they aren't too useful.

We can't send post fields, because we want to send JSON, not pretend to be a form (the merits of an API which accepts POST requests with data in form-format is an interesting debate). Instead, we create the correct JSON data, set that as the body of the POST request, and also set the headers correctly so that the server that receives this request will understand what we sent:

$data = array("name" => "Hagrid", "age" => "36");                                                                    
$data_string = json_encode($data);                                                                                   
 
$ch = curl_init('http://api.local/rest/users');                                                                      
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");                                                                     
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);                                                                  
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);                                                                      
curl_setopt($ch, CURLOPT_HTTPHEADER, array(                                                                          
    'Content-Type: application/json',                                                                                
    'Content-Length: ' . strlen($data_string))                                                                       
);                                                                                                                   
 
$result = curl_exec($ch);

All these settings are pretty well explained on the curl_setopt() page, but basically the idea is to set the request to be a POST request, set the json-encoded data to be the body, and then set the correct headers to describe that post body. The CURLOPT_RETURNTRANSFER is purely so that the response from the remote server gets placed in $result rather than echoed. If you're sending JSON data with PHP, I hope this might help!

20 thoughts on “POSTing JSON Data With PHP cURL

  1. Hello Lorna,

    I just had the same challenge the other day and got to the same conclusion as your snippet.

    Was fairly well documented on the PHP manual as you also pointed out.

    Thanks for sharing this little gem of knowledge.

    Cheers,
    Peter

  2. Thanks, I tried doing something similar style, but didn't set the header to application/json . I don't remember if it worked or not (it was a quick four liner suggestion to a colleague). But what happens if you forget setting the application/json header ?

    • If you don't set the header correctly, the service you are posting to may not understand what it is that you sent - the exact outcome depends entirely on the service though

      • Thanks Lorna.
        Looking at replies below (and I don't know much about script hijacking), I think I will stick setting application/json in the http-header. And if I am writing a server I will (try) not accept simple plain/text.
        Ohh BTW, I learned a lot from the slides that you linked in this post. I asked my colleague to read slide 39 - 42 for a quick introduction to SOAP. Pretty interesting stuff !

  3. Same thing without curl as a dependency (for the newbies who don't know about the excellent PHP's streams API):

    $data = array('name' => 'Hagrid', 'age' => '36');
    $data_string = json_encode($data);

    $result = file_get_contents('http://api.local/rest/users', null, stream_context_create(array(
    'http' => array(
    'method' => 'POST',
    'header' => 'Content-Type: application/json' . "\r\n"
    . 'Content-Length: ' . strlen($data_string) . "\r\n",
    'content' => $data_string,
    ),
    )));

    • Thanks for adding the streams example, that's nice! Streams are pretty awesome but as you say, they're not as widely used or understood as they should be

  4. Pingback: Lorna Mitchell Blog: Buchung JSON-Daten mit PHP cURL | PHP Boutique

  5. Actually, you can trim down the request a bit and keep it simple.

    You don't have to specify the content-length. It will be calculated automatically and appended to the headers.

    Also, you don't have to declare the request as a post request explicitly. If you are setting the POSTFIELDS option for curl, curl will convert the request type to POST.

  6. Pingback: Lorna Mitchell’s Blog: POSTing JSON Data With PHP cURL | Scripting4You Blog

  7. Hey Lorna,

    Could you give any examples of any of the discussions you elude to on the topic of accepting POST requests with data in form-format?

    Cheers
    /Matt

  8. Pingback: POSTing JSON Data With PHP cURL | PHP | Syngu

  9. Pingback: Post JSON, XML data With cURL and receive it on other end « TechnoReaders.com

  10. Thank you very much for this post, I've been struggling as a non-programmer to attempt to submit some basic form data to an API and this helped immensely.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">