Building a REST API with PHP


Introduction

In modern web development, RESTful APIs are essential for creating scalable, maintainable, and secure web applications. Whether you're building a PHP backend for a mobile app or exposing data to third-party services, creating a REST API in PHP is a foundational skill.

In this detailed tutorial, you'll learn how to build a REST API with PHP and MySQL, handle GET, POST, PUT, DELETE requests, return JSON responses, and follow REST API best practices using vanilla PHP (no framework). We'll also touch on security, error handling, and proper API structure.

What is a REST API?

REST (Representational State Transfer) is an architectural style that uses HTTP methods to interact with resources in a stateless manner. A REST API allows client applications to perform operations such as Create, Read, Update, and Delete (CRUD).

Common HTTP Methods:

Method Action
GET Read data
POST Create new data
PUT Update data
DELETE Remove data

Key Features of a RESTful API

  • Stateless: Each request is independent.
  • Resource-based URLs: Example: /api/users/1
  • HTTP methods for actions: GET for reading, POST for creating, etc.
  • JSON format for data exchange
  • Use of standard HTTP status codes

Tools Required

  • PHP (v7.4 or later)
  • MySQL database
  • Apache or Nginx (or use XAMPP/LAMP/WAMP)
  • Postman (for testing REST API)
  • Basic knowledge of PHP and MySQL

Project Structure

/api
  ├── db.php
  ├── users.php
  └── .htaccess

Step 1: Create MySQL Database and Table

CREATE DATABASE rest_api_db;

USE rest_api_db;

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) NOT NULL UNIQUE,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Step 2: Database Connection (db.php)

connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
?>

Step 3: Create the REST API Logic (users.php)

query("SELECT * FROM users WHERE id = $id");
            echo json_encode($result->fetch_assoc());
        } else {
            $result = $conn->query("SELECT * FROM users");
            $users = [];
            while($row = $result->fetch_assoc()) {
                $users[] = $row;
            }
            echo json_encode($users);
        }
        break;

    case 'POST':
        $data = json_decode(file_get_contents("php://input"), true);
        $name = $conn->real_escape_string($data['name']);
        $email = $conn->real_escape_string($data['email']);

        $query = "INSERT INTO users (name, email) VALUES ('$name', '$email')";
        if ($conn->query($query)) {
            echo json_encode(['message' => 'User created successfully']);
        } else {
            http_response_code(400);
            echo json_encode(['error' => 'User creation failed']);
        }
        break;

    case 'PUT':
        if (!isset($_GET['id'])) {
            http_response_code(400);
            echo json_encode(['error' => 'ID is required']);
            break;
        }

        $id = intval($_GET['id']);
        $data = json_decode(file_get_contents("php://input"), true);
        $name = $conn->real_escape_string($data['name']);
        $email = $conn->real_escape_string($data['email']);

        $query = "UPDATE users SET name='$name', email='$email' WHERE id=$id";
        if ($conn->query($query)) {
            echo json_encode(['message' => 'User updated successfully']);
        } else {
            http_response_code(400);
            echo json_encode(['error' => 'Update failed']);
        }
        break;

    case 'DELETE':
        if (!isset($_GET['id'])) {
            http_response_code(400);
            echo json_encode(['error' => 'ID is required']);
            break;
        }

        $id = intval($_GET['id']);
        $query = "DELETE FROM users WHERE id=$id";
        if ($conn->query($query)) {
            echo json_encode(['message' => 'User deleted']);
        } else {
            http_response_code(400);
            echo json_encode(['error' => 'Deletion failed']);
        }
        break;

    default:
        http_response_code(405);
        echo json_encode(['error' => 'Method Not Allowed']);
        break;
}
?>

Step 4: Enable URL Rewriting with .htaccess

For clean URLs like /api/users.php?id=1, create a .htaccess file in the api/ directory:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]

Step 5: Testing REST API with Postman

  • GET http://localhost/api/users.php - Fetch all users
  • GET http://localhost/api/users.php?id=1 - Fetch user by ID
  • POST http://localhost/api/users.php
    {
      "name": "John Doe",
      "email": "john@example.com"
    }
  • PUT http://localhost/api/users.php?id=1
    {
      "name": "John Smith",
      "email": "johnsmith@example.com"
    }
  • DELETE http://localhost/api/users.php?id=1

REST API Best Practices in PHP

  • Use prepared statements (with PDO or MySQLi) to prevent SQL injection
  • Return HTTP status codes like 200, 400, 404, and 500
  • Always validate and sanitize input data
  • Use JSON format consistently for request and response
  • Include helpful error messages
  • Secure the API with API keys or JWT

Secure Your PHP REST API

  • Use HTTPS to encrypt data in transit
  • Limit request rate to prevent DDoS attacks
  • Authenticate users using tokens or OAuth
  • Validate input on both client and server side
  • Log errors and monitor suspicious activity