PHP

Building a Generic API Wrapper Class (PHP)

Develop a reusable PHP class to efficiently interact with various RESTful APIs, centralizing HTTP requests, header management, and error handling.

<?php

class ApiClient {
    private $baseUrl;
    private $headers = [];
    private $lastError = null;

    public function __construct($baseUrl, $defaultHeaders = []) {
        $this->baseUrl = rtrim($baseUrl, '/');
        $this->headers = array_merge([
            'Content-Type: application/json',
            'Accept: application/json'
        ], $defaultHeaders);
    }

    public function setHeader($name, $value) {
        // Remove existing header with the same name before adding
        $this->headers = array_filter($this->headers, function($header) use ($name) {
            return strpos($header, $name . ':') !== 0;
        });
        $this->headers[] = "$name: $value";
        return $this;
    }

    public function setAuthToken($token) {
        return $this->setHeader('Authorization', 'Bearer ' . $token);
    }

    private function makeRequest($method, $path, $data = null) {
        $url = $this->baseUrl . '/' . ltrim($path, '/');
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->headers);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30 second timeout

        switch (strtoupper($method)) {
            case 'POST':
                curl_setopt($ch, CURLOPT_POST, true);
                if ($data !== null) {
                    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
                }
                break;
            case 'PUT':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
                if ($data !== null) {
                    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
                }
                break;
            case 'DELETE':
                curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
                break;
            // GET is default
        }

        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);

        if ($response === false) {
            $this->lastError = "cURL Error: " . $error;
            return false;
        }

        $decodedResponse = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            $this->lastError = "JSON Decode Error: " . json_last_error_msg() . " - Raw: " . $response;
            return false;
        }

        if ($httpCode >= 400) {
            $this->lastError = "API Error (HTTP $httpCode): " . ($decodedResponse['message'] ?? 'Unknown error');
            return false;
        }

        $this->lastError = null; // Clear error on success
        return $decodedResponse;
    }

    public function get($path) {
        return $this->makeRequest('GET', $path);
    }

    public function post($path, $data) {
        return $this->makeRequest('POST', $path, $data);
    }

    public function put($path, $data) {
        return $this->makeRequest('PUT', $path, $data);
    }

    public function delete($path) {
        return $this->makeRequest('DELETE', $path);
    }

    public function getLastError() {
        return $this->lastError;
    }
}

// Example Usage:
/*
// require_once 'ApiClient.php'; // If in a separate file

$apiClient = new ApiClient('https://jsonplaceholder.typicode.com');

// Set a custom header or auth token
$apiClient->setAuthToken('YOUR_SUPER_SECRET_TOKEN');

// GET request
$posts = $apiClient->get('/posts');
if ($posts) {
    // print_r($posts);
    // echo "Fetched " . count($posts) . " posts.
";
} else {
    // echo "Error fetching posts: " . $apiClient->getLastError() . "
";
}

// POST request
$newPost = [
    'title' => 'foo',
    'body' => 'bar',
    'userId' => 1,
];
$createdPost = $apiClient->post('/posts', $newPost);
if ($createdPost) {
    // echo "Created post with ID: " . $createdPost['id'] . "
";
    // print_r($createdPost);
} else {
    // echo "Error creating post: " . $apiClient->getLastError() . "
";
}
*/
How it works: This PHP `ApiClient` class provides a generic wrapper for interacting with RESTful APIs. It centralizes common API tasks like setting base URLs, managing headers (including authorization tokens), and making `GET`, `POST`, `PUT`, and `DELETE` requests. The class handles `cURL` execution, JSON decoding, and basic error detection for network issues, API errors (HTTP 4xx/5xx), and JSON parsing, making API integrations cleaner and more maintainable.

Need help integrating this into your project?

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

Hire DigitalCodeLabs