PHP
PHP: Consuming a REST API with `cURL` and Error Handling
Demonstrates how to make robust REST API requests in PHP using `cURL`, including proper error handling, JSON parsing, and custom headers for secure communication.
<?php
/**
* Fetches data from a REST API using cURL.
*
* @param string $url The API endpoint URL.
* @param string $method HTTP method (GET, POST, PUT, DELETE).
* @param array $headers Optional HTTP headers.
* @param array|string|null $data Optional request body data (for POST/PUT).
* @param int $timeout Timeout for the cURL request in seconds.
* @return array|false Returns the decoded JSON response as an array on success, false on failure.
*/
function callRestApi(string $url, string $method = 'GET', array $headers = [], $data = null, int $timeout = 30)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return the response as a string
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // Set custom headers
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
// Handle SSL certificate verification (recommended for production)
// curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
// curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
// curl_setopt($ch, CURLOPT_CAINFO, '/path/to/your/cacert.pem'); // Path to CA certificate bundle
switch (strtoupper($method)) {
case 'POST':
curl_setopt($ch, CURLOPT_POST, true);
if ($data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? json_encode($data) : $data);
}
break;
case 'PUT':
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
if ($data) {
curl_setopt($ch, CURLOPT_POSTFIELDS, is_array($data) ? json_encode($data) : $data);
}
break;
case 'DELETE':
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
break;
case 'GET':
default:
// GET is default, no specific options needed for method itself
break;
}
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
if ($curlError) {
error_log("cURL Error for {$url}: {$curlError}");
curl_close($ch);
return false;
}
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 300) {
$decodedResponse = json_decode($response, true);
if (json_last_error() === JSON_ERROR_NONE) {
return $decodedResponse;
} else {
error_log("JSON Decoding Error for {$url}: " . json_last_error_msg());
return false;
}
} else {
error_log("API Call Failed for {$url} with HTTP Status: {$httpCode}. Response: {$response}");
return false;
}
}
// --- Example Usage ---
// 1. GET Request
$get_url = 'https://jsonplaceholder.typicode.com/posts/1';
$get_headers = [
'Accept: application/json',
// 'Authorization: Bearer YOUR_API_TOKEN'
];
$get_result = callRestApi($get_url, 'GET', $get_headers);
if ($get_result) {
echo "GET Request Successful:
";
print_r($get_result);
} else {
echo "GET Request Failed.
";
}
echo "
--------------------------------
";
// 2. POST Request
$post_url = 'https://jsonplaceholder.typicode.com/posts';
$post_data = [
'title' => 'foo',
'body' => 'bar',
'userId' => 1,
];
$post_headers = [
'Content-Type: application/json',
'Accept: application/json',
];
$post_result = callRestApi($post_url, 'POST', $post_headers, $post_data);
if ($post_result) {
echo "POST Request Successful:
";
print_r($post_result);
} else {
echo "POST Request Failed.
";
}
echo "
--------------------------------
";
// 3. Error Handling Example (e.g., non-existent endpoint)
$error_url = 'https://jsonplaceholder.typicode.com/non-existent-endpoint';
$error_result = callRestApi($error_url, 'GET');
if (!$error_result) {
echo "Error handling test: API call correctly failed for {$error_url}. Check logs for details.
";
}
?>
How it works: This PHP snippet provides a `callRestApi` function that serves as a robust wrapper for making HTTP requests to REST APIs using the `cURL` extension. It supports various HTTP methods (GET, POST, PUT, DELETE), custom headers, and sending JSON data in the request body. The function includes critical error handling: it checks for cURL execution errors, verifies the HTTP status code (2xx for success), and handles JSON decoding failures. This centralized approach to API communication ensures consistency, simplifies error reporting via `error_log`, and makes your backend integrations more reliable and easier to maintain. SSL verification options are also included for production readiness.