Read JSON request data with PHP
While working on an API project, I realised that I actually didn’t know how to receive JSON data in the request body with PHP. Turns out it’s really simple with the php://input
stream.
Most projects we work on with PHP rely on forms to receive data. That’s what the $_POST
superglobal is for: it contains all information passed via HTTP POST when sending data with content type application/x-www-form-urlencoded
or multipart/form-data
.
But what if you use the application/json
content type? Up until PHP 5.6 we could use the $HTTP_RAW_POST_DATA
superglobal, but this has been deprecated. Instead we should use the php://input
stream to read raw data from the request body.
Below is an example script. The comments explain what’s happening:
<?php
// Only allow POST requests
if (strtoupper($_SERVER['REQUEST_METHOD']) != 'POST') {
throw new Exception('Only POST requests are allowed');
}
// Make sure Content-Type is application/json
$content_type = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
if (stripos($content_type, 'application/json') === false) {
throw new Exception('Content-Type must be application/json');
}
// Read the input stream
$body = file_get_contents("php://input");
// Decode the JSON object
$object = json_decode($body, true);
// Throw an exception if decoding failed
if (!is_array($object)) {
throw new Exception('Failed to decode JSON object');
}
// Display the object
print_r($object);
Let’s give this a quick whirl. Save the example as script.php
and start the standalone PHP server with php -S localhost:8080 script.php
.
Now let’s send it a POST request containing JSON data using cURL:
curl -X POST \
-d '{"foo": ["bar", "baz"]}' \
-H "Content-Type: application/json" \
http://localhost:8080
Your JSON object should be printed out:
Array
(
[foo] => Array
(
[0] => bar
[1] => baz
)
)
Easy!