Как написать REST API на PHP за 30 минут: пошаговое руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как написать REST API на PHP за 30 минут

REST API (Representational State Transfer) — это архитектурный стиль взаимодействия компонентов распределённого приложения в сети. В современной веб-разработке REST API является стандартом для создания бэкенда мобильных приложений, SPA (Single Page Application) и микросервисов. В этой статье мы покажем, как написать простой, но полностью рабочий REST API на PHP всего за 30 минут.

Мы создадим API для управления списком задач (Todo List) с поддержкой CRUD-операций (Create, Read, Update, Delete). Вы узнаете, как организовать маршрутизацию, обрабатывать JSON-запросы и подключать базу данных MySQL.

Подготовка окружения

Для работы вам понадобится:

  • Веб-сервер Apache или Nginx с поддержкой PHP 7.4+
  • MySQL или MariaDB
  • Редактор кода (VS Code, PhpStorm)
  • Postman или curl для тестирования API

Создайте структуру проекта:

todo-api/
├── index.php          # Точка входа (роутер)
├── config.php         # Настройки подключения к БД
├── api/
│   └── tasks.php      # Логика работы с задачами
└── .htaccess          # Настройки перезаписи URL

Шаг 1: Настройка .htaccess и точки входа

Создайте файл .htaccess для перенаправления всех запросов на index.php:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]

Теперь создадим index.php — наш главный роутер:

<?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, Authorization");

// Обработка preflight запросов
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit();
}

require_once 'config.php';
require_once 'api/tasks.php';

$url = isset($_GET['url']) ? rtrim($_GET['url'], '/') : '';
$urlParts = explode('/', $url);
$resource = $urlParts[0] ?? '';
$id = $urlParts[1] ?? null;

switch ($resource) {
    case 'tasks':
        $tasks = new Tasks();
        echo $tasks->handleRequest($_SERVER['REQUEST_METHOD'], $id);
        break;
    default:
        http_response_code(404);
        echo json_encode(["message" => "Resource not found"]);
        break;
}
?>

Шаг 2: Подключение к базе данных

Создайте config.php с настройками подключения:

<?php
class Database {
    private $host = "localhost";
    private $db_name = "todo_api";
    private $username = "root";
    private $password = "";
    public $conn;

    public function getConnection() {
        $this->conn = null;
        try {
            $this->conn = new PDO(
                "mysql:host=" . $this->host . ";dbname=" . $this->db_name,
                $this->username,
                $this->password
            );
            $this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch(PDOException $e) {
            http_response_code(500);
            echo json_encode(["message" => "Database connection error"]);
            exit();
        }
        return $this->conn;
    }
}
?>

Создайте таблицу в MySQL:

CREATE DATABASE todo_api;
USE todo_api;

CREATE TABLE tasks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    description TEXT,
    status ENUM('pending', 'completed') DEFAULT 'pending',
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

Шаг 3: Реализация CRUD-операций

Создайте файл api/tasks.php с основной логикой:

<?php
class Tasks {
    private $conn;
    private $table = "tasks";

    public function __construct() {
        $database = new Database();
        $this->conn = $database->getConnection();
    }

    public function handleRequest($method, $id) {
        switch ($method) {
            case 'GET':
                return $id ? $this->getTask($id) : $this->getAllTasks();
            case 'POST':
                return $this->createTask();
            case 'PUT':
                return $this->updateTask($id);
            case 'DELETE':
                return $this->deleteTask($id);
            default:
                http_response_code(405);
                return json_encode(["message" => "Method not allowed"]);
        }
    }

    // Получить все задачи
    private function getAllTasks() {
        $query = "SELECT * FROM " . $this->table . " ORDER BY created_at DESC";
        $stmt = $this->conn->prepare($query);
        $stmt->execute();
        $tasks = $stmt->fetchAll(PDO::FETCH_ASSOC);
        http_response_code(200);
        return json_encode($tasks);
    }

    // Получить одну задачу по ID
    private function getTask($id) {
        $query = "SELECT * FROM " . $this->table . " WHERE id = :id";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':id', $id);
        $stmt->execute();
        $task = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($task) {
            http_response_code(200);
            return json_encode($task);
        } else {
            http_response_code(404);
            return json_encode(["message" => "Task not found"]);
        }
    }

    // Создать новую задачу
    private function createTask() {
        $data = json_decode(file_get_contents("php://input"));

        if (!isset($data->title) || empty(trim($data->title))) {
            http_response_code(400);
            return json_encode(["message" => "Title is required"]);
        }

        $query = "INSERT INTO " . $this->table . " (title, description) VALUES (:title, :description)";
        $stmt = $this->conn->prepare($query);
        $stmt->bindParam(':title', $data->title);
        $stmt->bindParam(':description', $data->description ?? '');

        if ($stmt->execute()) {
            $lastId = $this->conn->lastInsertId();
            http_response_code(201);
            return json_encode([
                "message" => "Task created",
                "id" => $lastId
            ]);
        } else {
            http_response_code(500);
            return json_encode(["message" => "Unable to create task"]);
        }
    }

    // Обновить задачу
    private function updateTask($id) {
        $data = json_decode(file_get_contents("php://input"));

        if (!$id) {
            http_response_code(400);
            return json_encode(["message" => "ID is required"]);
        }

        $                

Блоги

Рекомендаций по книгам