PHP REST API

PHP REST API

Build a clean REST API in pure PHP — no framework required — responding with JSON based on HTTP method and URL.

1 - Setup (index.php)

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");

if ($_SERVER["REQUEST_METHOD"] === "OPTIONS") { exit(0); }

$method = $_SERVER["REQUEST_METHOD"];
$uri    = trim(parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH), "/");
$parts  = explode("/", $uri); // ["api", "posts", "5"]

$resource = $parts[1] ?? "";
$id       = isset($parts[2]) && is_numeric($parts[2]) ? (int)$parts[2] : null;

2 - Response Helper

function respond(int $status, array $body): never {
    http_response_code($status);
    echo json_encode($body, JSON_THROW_ON_ERROR);
    exit;
}

3 - Router

match (true) {
    $resource === "posts" && $method === "GET"  && $id === null => respondAll(),
    $resource === "posts" && $method === "GET"  && $id !== null => respondOne($id),
    $resource === "posts" && $method === "POST"                 => createOne(),
    $resource === "posts" && $method === "PUT"  && $id !== null => updateOne($id),
    $resource === "posts" && $method === "DELETE" && $id !== null => deleteOne($id),
    default => respond(404, ["error" => "Not found"])
};

4 - Handlers

function respondAll(): never {
    respond(200, ["data" => getPosts()]);
}

function createOne(): never {
    $body = json_decode(file_get_contents("php://input"), true, 512, JSON_THROW_ON_ERROR);
    if (empty($body["title"])) {
        respond(422, ["error" => "Title is required"]);
    }
    $id = createPost($body["title"], $body["body"] ?? "");
    respond(201, ["id" => $id, "message" => "Created"]);
}

Note: For production APIs use a framework like Slim or Laravel. They handle routing, middleware, authentication, rate limiting, and serialisation far more robustly than a hand-rolled solution.

-Tip-