Alaa Amer Articles

We offer a comprehensive collection of essential educational articles in web development to turn your ideas into digital reality

REST APIs in PHP: Building Professional Web Services

PHP 2025-12-31 Alaa Amer

REST APIs in PHP: Building Professional Web Services

Specialized Guide by Alaa Amer – Professional Web & App Developer

REST APIs have become the backbone of modern applications. In this article, you'll learn how to build professional APIs using pure PHP with best practices.

2️⃣ Building Simple API Framework

Router Class:

<?php
// classes/Router.php
class Router {
    private $routes = [];

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

    public function post($path, $handler) {
        $this->addRoute('POST', $path, $handler);
    }

    public function put($path, $handler) {
        $this->addRoute('PUT', $path, $handler);
    }

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

    private function addRoute($method, $path, $handler) {
        $this->routes[] = [
            'method' => $method,
            'path' => $path,
            'handler' => $handler
        ];
    }

    public function resolve() {
        $method = $_SERVER['REQUEST_METHOD'];
        $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

        // Remove /api from beginning if present
        $path = preg_replace('#^/api#', '', $path);

        foreach ($this->routes as $route) {
            if ($route['method'] === $method) {
                $pattern = preg_replace('/\{[^}]+\}/', '([^/]+)', $route['path']);
                $pattern = '#^' . $pattern . '$#';

                if (preg_match($pattern, $path, $matches)) {
                    array_shift($matches); // Remove full match
                    return $this->executeHandler($route['handler'], $matches);
                }
            }
        }

        return $this->notFound();
    }

    private function executeHandler($handler, $params = []) {
        if (is_callable($handler)) {
            return call_user_func_array($handler, $params);
        }

        if (is_array($handler) && count($handler) === 2) {
            list($class, $method) = $handler;
            $instance = new $class();
            return call_user_func_array([$instance, $method], $params);
        }

        return $this->notFound();
    }

    private function notFound() {
        http_response_code(404);
        return json_encode(['error' => 'Route not found']);
    }
}

Response Class:

<?php
// classes/Response.php
class Response {

    public static function json($data, $statusCode = 200, $headers = []) {
        http_response_code($statusCode);

        // Add default headers
        header('Content-Type: application/json; charset=utf-8');
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
        header('Access-Control-Allow-Headers: Content-Type, Authorization');

        // Add custom headers
        foreach ($headers as $header => $value) {
            header("$header: $value");
        }

        echo json_encode($data, JSON_UNESCAPED_UNICODE);
        exit;
    }

    public static function success($data = null, $message = 'Success', $statusCode = 200) {
        $response = [
            'success' => true,
            'message' => $message,
            'timestamp' => date('Y-m-d H:i:s')
        ];

        if ($data !== null) {
            $response['data'] = $data;
        }

        self::json($response, $statusCode);
    }

    public static function error($message, $statusCode = 400, $errors = null) {
        $response = [
            'success' => false,
            'message' => $message,
            'timestamp' => date('Y-m-d H:i:s')
        ];

        if ($errors !== null) {
            $response['errors'] = $errors;
        }

        self::json($response, $statusCode);
    }
}

4️⃣ Data Models

<?php
// models/User.php
class User {
    private $db;

    public function __construct($database) {
        $this->db = $database;
    }

    public function findAll($limit = 10, $offset = 0) {
        $stmt = $this->db->prepare("
            SELECT id, name, email, created_at
            FROM users
            ORDER BY created_at DESC
            LIMIT :limit OFFSET :offset
        ");

        $stmt->bindParam(':limit', $limit, PDO::PARAM_INT);
        $stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function findById($id) {
        $stmt = $this->db->prepare("
            SELECT id, name, email, created_at
            FROM users
            WHERE id = :id
        ");

        $stmt->bindParam(':id', $id, PDO::PARAM_INT);
        $stmt->execute();

        return $stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function create($data) {
        $stmt = $this->db->prepare("
            INSERT INTO users (name, email, password, created_at)
            VALUES (:name, :email, :password, NOW())
        ");

        $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);

        $stmt->bindParam(':name', $data['name']);
        $stmt->bindParam(':email', $data['email']);
        $stmt->bindParam(':password', $data['password']);

        if ($stmt->execute()) {
            return $this->findById($this->db->lastInsertId());
        }

        return false;
    }

    public function authenticate($email, $password) {
        $stmt = $this->db->prepare("
            SELECT id, name, email, password
            FROM users
            WHERE email = :email
        ");

        $stmt->bindParam(':email', $email);
        $stmt->execute();

        $user = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($user && password_verify($password, $user['password'])) {
            unset($user['password']); // Remove password from result
            return $user;
        }

        return false;
    }
}

6️⃣ Main API File

<?php
// api/index.php
require_once '../config/config.php';
require_once '../classes/Database.php';
require_once '../classes/Router.php';
require_once '../classes/Response.php';
require_once '../classes/JWTAuth.php';
require_once '../models/User.php';
require_once '../controllers/UserController.php';

// Handle CORS
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
    header('Access-Control-Allow-Headers: Content-Type, Authorization');
    http_response_code(200);
    exit;
}

$router = new Router();

// Authentication routes
$router->post('/auth/login', [AuthController::class, 'login']);
$router->post('/auth/register', [AuthController::class, 'register']);

// User routes
$router->get('/users', [UserController::class, 'index']);
$router->get('/users/{id}', [UserController::class, 'show']);
$router->post('/users', [UserController::class, 'store']);

// Handle errors
try {
    echo $router->resolve();
} catch (Exception $e) {
    Response::error('Server error: ' . $e->getMessage(), 500);
}

💡 Performance Optimization Tips

  1. Use Caching: Redis or Memcached for frequent data
  2. Database Indexing: Indexes on frequently queried columns
  3. Rate Limiting: Limit requests per user
  4. Compression: Compress large responses
  5. API Versioning: Plan for future versions

Next Step

Learn GraphQL and API Documentation using OpenAPI/Swagger.

📩 Need help building complex APIs?

PHP REST API Web Services JSON HTTP Authentication
Article Category
PHP

REST APIs in PHP: Building Professional Web Services

Complete guide to developing REST APIs using PHP with best practices, security, and practical examples.

REST APIs in PHP: Building Professional Web Services
01

Consultation & Communication

Direct communication via WhatsApp or phone to understand your project needs precisely.

02

Planning & Scheduling

Creating clear work plan with specific timeline for each project phase.

03

Development & Coding

Building projects with latest technologies ensuring high performance and security.

04

Testing & Delivery

Comprehensive testing and thorough review before final project delivery.

Alaa Amer
Alaa Amer

Professional web developer with over 10 years of experience in building innovative digital solutions.

Need This Service?

Contact me now for a free consultation and quote

WhatsApp Your satisfaction is our ultimate goal

What We Offer

  • Website Maintenance & Updates

    Keep your website secure updated optimized

  • API Integration

    Connect your systems with powerful APIs

  • Database Design & Optimization

    Faster queries cleaner structure fewer issues

  • Website Security Hardening

    Protect your site from cyber threats

  • Automation & Scripts

    Automate repetitive tasks and save time

Have Questions?

Call Us Now

00201014714795