Как написать REST API на PHP за 30 минут
Создание собственного REST API — один из ключевых навыков современного backend-разработчика. Многие новички думают, что для этого нужны тяжелые фреймворки вроде Laravel или Symfony. На самом деле, базовый REST API на чистом PHP можно написать буквально за полчаса. В этой статье мы разберем пошаговый процесс создания RESTful сервиса, который можно сразу использовать в реальных проектах — от мобильных приложений до одностраничных сайтов.
Мы не будем использовать сторонние библиотеки. Весь код будет написан на ванильном PHP. Вы научитесь обрабатывать HTTP-запросы, работать с JSON, организовывать маршрутизацию и возвращать правильные HTTP-статусы. Поехали!
1. Структура проекта и подготовка
Прежде чем писать код, создадим простую структуру файлов. Для нашего API понадобится всего несколько файлов:
index.php— точка входа, которая будет обрабатывать все запросы;.htaccess— для перенаправления всех запросов на index.php (если используете Apache);config.php— файл с настройками подключения к базе данных (опционально).
Создайте папку проекта, например, my-rest-api, и поместите туда эти файлы.
Настройка .htaccess
Чтобы все запросы попадали в наш главный скрипт, создайте файл .htaccess в корне проекта:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Этот код перенаправляет все запросы, которые не ведут к реальным файлам или папкам, на index.php. Параметр QSA сохраняет query-строку.
2. Маршрутизация и обработка запросов
Теперь напишем главный файл — index.php. Он будет принимать запрос, определять метод HTTP (GET, POST, PUT, DELETE) и путь, а затем вызывать нужный обработчик.
Базовая маршрутизация
Начнем с простого примера. Создадим массив маршрутов и функцию для их обработки:
<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type');
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
// Убираем слеш в конце
$path = rtrim($path, '/');
// Простая маршрутизация
switch (true) {
case $path === '/api/users' && $method === 'GET':
getUsers();
break;
case $path === '/api/users' && $method === 'POST':
createUser();
break;
case preg_match('/^\/api\/users\/(\d+)$/', $path, $matches) && $method === 'GET':
getUser($matches[1]);
break;
default:
http_response_code(404);
echo json_encode(['error' => 'Route not found']);
break;
}
function getUsers() {
// Заглушка
echo json_encode(['users' => ['Alice', 'Bob', 'Charlie']]);
}
function getUser($id) {
echo json_encode(['user' => ['id' => $id, 'name' => 'User ' . $id]]);
}
function createUser() {
$input = json_decode(file_get_contents('php://input'), true);
echo json_encode(['message' => 'User created', 'data' => $input]);
}
?>
Обратите внимание на несколько важных моментов:
- Мы устанавливаем заголовок
Content-Type: application/json— все ответы будут в JSON. - Заголовки CORS разрешают запросы с любого домена (для разработки).
- Тело POST/PUT запроса читается через
php://input.
3. Работа с базой данных
Настоящий API редко работает с заглушками. Добавим подключение к MySQL через PDO. Создайте файл config.php:
<?php
define('DB_HOST', 'localhost');
define('DB_NAME', 'my_api_db');
define('DB_USER', 'root');
define('DB_PASS', '');
function getDB() {
static $pdo = null;
if ($pdo === null) {
try {
$pdo = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME . ";charset=utf8",
DB_USER,
DB_PASS,
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['error' => 'Database connection failed']);
exit;
}
}
return $pdo;
}
?>
Теперь подключим этот файл в index.php и перепишем функции для работы с реальными данными. Пример для получения списка пользователей:
require_once 'config.php';
function getUsers() {
$db = getDB();
$stmt = $db->query("SELECT id, name, email FROM users");
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode(['users' => $users]);
}
function createUser() {
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['name']) || !isset($input['email'])) {
http_response_code(400);
echo json_encode(['error' => 'Name and email are required']);
return;
}
$db = getDB();
$stmt = $db->prepare("INSERT INTO users (name, email) VALUES (:name, :email)");
$stmt->execute(['name' => $input['name'], 'email' => $input['email']]);
http_response_code(201);
echo json_encode(['message' => 'User created', 'id' => $db->lastInsertId()]);
}
Мы добавили валидацию входных данных и возвращаем HTTP-статус 201 при успешном создании. Если данные невалидны — возвращаем 400 Bad Request.
4. Полный пример: CRUD для сущности "Task"
Соберем всё вместе и создадим полноценный CRUD для задач (tasks). Вот финальный код index.php:
<?php
require_once 'config.php';
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE');
header('Access-Control-Allow-Headers: Content-Type');
$method = $_SERVER['REQUEST_METHOD'];
$path = parse_url($_SERVER['REQUEST_URI'],