Основные подходы к созданию API на PHP
Разработка API сервера на PHP требует выбора правильной архитектуры и инструментов. В этой статье рассматриваются различные варианты, от простых решений до современных фреймворков, с подробными примерами кода и разбором типичных проблем.
Эффективное решение: микрофреймворк Slim 4
Как организовать REST API с минимальными затратами на настройку и высокой производительностью?
Slim 4 - лёгкий фреймворк, идеально подходящий для создания API. Он предоставляет маршрутизатор, middleware, контейнер зависимостей и удобную обработку ответов.
// Установка через Composer
composer require slim/slim:4.*
// index.php
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$app = AppFactory::create();
// Маршрут GET /api/users
$app->get('/api/users', function (Request $request, Response $response, $args) {
$users = [
['id' => 1, 'name' => 'Иван'],
['id' => 2, 'name' => 'Мария']
];
$payload = json_encode($users);
$response->getBody()->write($payload);
return $response->withHeader('Content-Type', 'application/json');
});
// Маршрут POST /api/users
$app->post('/api/users', function (Request $request, Response $response, $args) {
$data = $request->getParsedBody();
// Валидация и сохранение
$newUser = ['id' => 3, 'name' => $data['name'] ?? 'Неизвестно'];
$payload = json_encode($newUser);
$response->getBody()->write($payload);
return $response->withHeader('Content-Type', 'application/json')->withStatus(201);
});
// Middleware для CORS
$app->add(function ($request, $handler) {
$response = $handler->handle($request);
return $response
->withHeader('Access-Control-Allow-Origin', '*')
->withHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization')
->withHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
});
$app->run();
Php api server (api сервер php)
Типичные ошибки и их решение:
- Ошибка 404 при обращении к маршруту - проверьте порядок маршрутов и метод HTTP.
- Ошибка 500 из-за некорректного JSON - убедитесь, что данные корректно декодируются через json_last_error().
- CORS ошибка в браузере - добавьте middleware для preflight-запросов (OPTIONS).
- Пустое тело ответа - проверьте, что контент записывается в поток $response->getBody().
Вариант 1: Чистый PHP без фреймворков
Как создать минимальный API сервер на нативном PHP без внешних зависимостей?
Подходит для простых проектов или обучения. Основная сложность - ручная маршрутизация и обработка ошибок.
// public/index.php
$method = $_SERVER['REQUEST_METHOD'];
$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
if ($method === 'GET' && $uri === '/api/users') {
$users = [['id'=>1,'name'=>'Анна'], ['id'=>2,'name'=>'Петр']];
echo json_encode($users);
exit;
}
if ($method === 'POST' && $uri === '/api/users') {
$data = json_decode(file_get_contents('php://input'), true);
if ($data === null) {
http_response_code(400);
echo json_encode(['error' => 'Неверный JSON']);
exit;
}
// Сохранение...
echo json_encode(['id'=>3, 'name'=>$data['name']]);
exit;
}
http_response_code(404);
echo json_encode(['error' => 'Не найден']);
Проблемы:
- Отсутствие автоматической маршрутизации - каждый новый endpoint добавляется вручную.
- Сложность с middlewares (аутентификация, логирование) - приходится писать вручную.
- Нет валидации входящих данных - требуется самому проверять типы и форматы.
Вариант 2: Laravel для полнофункционального API
Как построить крупное масштабируемое API с авторизацией и ORM?
Laravel предлагает готовые решения: маршрутизация через routes/api.php, Eloquent ORM, встроенная аутентификация (Sanctum или Passport), валидация и ресурсы.
// routes/api.php
use App\Http\Controllers\UserController;
Route::get('/users', [UserController::class, 'index']);
Route::post('/users', [UserController::class, 'store']);
Route::middleware('auth:sanctum')->group(function () {
Route::get('/user', function (Request $request) {
return $request->user();
});
});
// UserController
public function index() {
return UserResource::collection(User::paginate(10));
}
public function store(Request $request) {
$validated = $request->validate([
'name' => 'required|string|max:255',
'email' => 'required|email|unique:users'
]);
$user = User::create($validated);
return new UserResource($user);
}
Возможные сложности:
- Избыточность для простых проектов - Laravel требует больше ресурсов.
- Необходимость изучения концепций фреймворка (Eloquent, Service Container).
- Настройка аутентификации для API (выбор Sanctum или Passport).
Вариант 3: Использование Lumen (микрофреймворк от Laravel)
Как получить Laravel-подобный инструмент с меньшим весом?
Lumen - именно микрофреймворк для API, сохраняет часть компонентов Laravel (Eloquent, валидация), но быстрее.
// composer.json: "laravel/lumen-framework": "^10.0"
// Пример маршрута
$router->get('/api/users', function () use ($router) {
return response()->json(User::all());
});
Вариант 4: FastRoute - библиотека маршрутизации без фреймворка
Как добавить только маршрутизацию в проект с чистым PHP?
FastRoute (nikic/FastRoute) поддерживает динамические маршруты, группы и middleware через обёртки.
use FastRoute\RouteCollector;
$dispatcher = FastRoute\simpleDispatcher(function(RouteCollector $r) {
$r->addRoute('GET', '/api/users', 'get_users');
$r->addRoute('POST', '/api/users', 'create_user');
});
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];
$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
case FastRoute\Dispatcher::FOUND:
$handler = $routeInfo[1];
$vars = $routeInfo[2];
// вызов обработчика
break;
case FastRoute\Dispatcher::NOT_FOUND:
// 404
break;
}