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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs