Guzzle provides several convenient methods to parse JSON responses from HTTP requests. Here's a comprehensive guide on different approaches and best practices.
Basic JSON Parsing
The most straightforward way to parse JSON responses in Guzzle:
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
$client = new Client();
try {
$response = $client->request('GET', 'https://api.example.com/users');
// Method 1: Using json_decode with getBody()
$data = json_decode($response->getBody(), true);
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception('Invalid JSON response: ' . json_last_error_msg());
}
print_r($data);
} catch (RequestException $e) {
echo 'Request failed: ' . $e->getMessage();
}
Using Guzzle's Built-in JSON Options
Guzzle 7+ provides convenient JSON request/response handling:
$client = new Client();
try {
// Send request and automatically decode JSON
$response = $client->request('GET', 'https://api.example.com/users', [
'headers' => [
'Accept' => 'application/json',
'Content-Type' => 'application/json'
]
]);
// Parse JSON response
$jsonData = json_decode($response->getBody()->getContents(), true);
// Access the data
foreach ($jsonData['users'] as $user) {
echo "Name: " . $user['name'] . "\n";
}
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
Sending JSON Data and Parsing Response
When sending JSON data to an API and parsing the response:
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\ServerException;
$client = new Client();
$postData = [
'name' => 'John Doe',
'email' => 'john@example.com'
];
try {
$response = $client->request('POST', 'https://api.example.com/users', [
'json' => $postData, // Automatically encodes to JSON
'headers' => [
'Accept' => 'application/json'
]
]);
// Parse the JSON response
$responseData = json_decode($response->getBody(), true);
echo "User created with ID: " . $responseData['id'];
} catch (ClientException $e) {
// Handle 4xx errors
$errorResponse = json_decode($e->getResponse()->getBody(), true);
echo 'Client error: ' . $errorResponse['message'];
} catch (ServerException $e) {
// Handle 5xx errors
echo 'Server error: ' . $e->getMessage();
}
Advanced JSON Parsing with Validation
More robust JSON parsing with content type validation:
function parseJsonResponse($response) {
// Check content type
$contentType = $response->getHeaderLine('Content-Type');
if (strpos($contentType, 'application/json') === false) {
throw new Exception('Response is not JSON format');
}
// Get response body
$body = $response->getBody()->getContents();
// Parse JSON
$data = json_decode($body, true);
// Check for JSON parsing errors
if (json_last_error() !== JSON_ERROR_NONE) {
throw new Exception('JSON parsing error: ' . json_last_error_msg());
}
return $data;
}
// Usage
try {
$client = new Client();
$response = $client->get('https://api.example.com/data');
$jsonData = parseJsonResponse($response);
print_r($jsonData);
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
Asynchronous JSON Parsing
For handling multiple JSON responses asynchronously:
use GuzzleHttp\Client;
use GuzzleHttp\Promise;
$client = new Client();
$promises = [
'users' => $client->getAsync('https://api.example.com/users'),
'posts' => $client->getAsync('https://api.example.com/posts'),
'comments' => $client->getAsync('https://api.example.com/comments')
];
try {
$responses = Promise\settle($promises)->wait();
foreach ($responses as $key => $response) {
if ($response['state'] === 'fulfilled') {
$jsonData = json_decode($response['value']->getBody(), true);
echo "$key data:\n";
print_r($jsonData);
} else {
echo "Failed to fetch $key: " . $response['reason']->getMessage() . "\n";
}
}
} catch (Exception $e) {
echo 'Error: ' . $e->getMessage();
}
Best Practices
- Always validate JSON: Use
json_last_error()
to check for parsing errors - Handle HTTP status codes: Check response status before parsing
- Verify content type: Ensure the response is actually JSON
- Use proper exception handling: Catch different types of Guzzle exceptions
- Set appropriate headers: Include
Accept: application/json
in requests - Handle empty responses: Check if response body is not empty before parsing
Common Pitfalls
- Not checking
json_last_error()
: Always verify JSON was parsed successfully - Assuming content type: Verify the response is actually JSON format
- Ignoring HTTP status codes: A 404 response might still contain JSON error details
- Memory issues with large responses: Use
getBody()->getContents()
for better memory management
This comprehensive approach ensures reliable JSON parsing with proper error handling in your Guzzle-based applications.