POSTing JSON To A Web Service With PHP

I needed to POST JSON formatted data to a RESTful web service using PHP earlier, so I thought I’d share my solution.

There are a couple of approaches that could be taken, using the CURL extension, or file_get_contents and a http context. I took the later way.

When POSTing JSON to a RESTful web service we don’t send post fields or pretend to be a form, instead we have to send the JSON data in body of the request, and let the web service know it’s JSON data by setting the Content-type header to application/json.

$article = new stdClass();
$article->title = "An example article";
$article->summary = "An example of posting JSON encoded data to a web service";

$json_data = json_encode($article);

$post = file_get_contents('http://localhost/rest/articles',null,stream_context_create(array(
    'http' => array(
        'protocol_version' => 1.1,
        'user_agent'       => 'PHPExample',
        'method'           => 'POST',
        'header'           => "Content-type: application/json\r\n".
                              "Connection: close\r\n" .
                              "Content-length: " . strlen($json_data) . "\r\n",
        'content'          => $json_data,
    ),
)));

if ($post) {
    echo $post;
} else {
    echo "POST failed";
}

Here I’m first creating an example PHP stdClass object, populating it with some data, then serialising it to a JSON string. The real magic is using file_get_contents to POST it over HTTP to my test web service. If the POST succeeds, then it’s displayed, else an error message is shown.

It’s important to note I send the header, Connection: close . Without this, your script will hang until the web server closes the connection. If we include it, then as soon as the data has POSTed the connection is closed and control returned to the script.

8 thoughts on “POSTing JSON To A Web Service With PHP”

  1. Great alternative to using CURL.

    Remember though that without including the following at the top of the initiation, then there will be no user-agent sent:

    ini_set(‘user_agent’, ‘Mozilla/5.0 (Windows NT 6.0) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.56 Safari/536.5’);

  2. i am getting HTTP/1.1 400 Bad Request using same code.

    $opts = array(
    ‘http’ =>array(
    ‘method’ => ‘POST’,
    ‘header’ => “Connection:closern”.
    “Content-Type:application/jsonrn”.
    “Content-Length:”.strlen($data).”rn”.
    “Authorization:Basic “.base64_encode(“$username:$password”),’content’=>$data));
    Any suggestion??

    1. The 400 response is coming from your web server, are you sure you are posting the correct data it is expecting?

  3. in your “if($post)” is redundant, it’ll always be true, since that var is allways created above 🙂 change that into “if($json_data)” that way you make sure there’s no error on json encoding

    1. $post will hold the return value of file_get_contents. This would be the data read back from the service, or FALSE on failure. So the if ($post) isn’t redundant.

      You are right that I’m not checking if the json was correctly encoded, but in my defence, this was a short example and I was concentrating more on the file_get_contents side of things.

    1. If you’re using something like PHP’s Slim Framework, you can do something like this

      $request = $app->request();
      $body = $request->getBody();
      $json = json_decode($body);

Comments are closed.