PHP-фреймворк — это готовый каркас веб-приложения на PHP: он принимает HTTP-запрос, по маршруту находит нужный обработчик, помогает работать с базой данных и шаблонами и возвращает ответ. Самые популярные PHP-фреймворки в 2026 году — Laravel и Symfony (полнофункциональные), Yii 2 и CodeIgniter 4 (более легкие full-stack), Slim (микрофреймворк для API) и Laminas (бывший Zend Framework, в основном в корпоративных и старых проектах).
Содержание
- Фреймворк, библиотека, CMS: в чем разница
- Сравнение популярных PHP-фреймворков
- Один маршрут в трех фреймворках
- Типичная ошибка: перенос привычек между фреймворками
- Как выбрать PHP-фреймворк под задачу
- Безопасность: что фреймворк дает, а что нет
- Если не получилось
- Выводы
- Где применяется / связь с практикой
- FAQ
Ниже — таблица версий, один маршрут в Slim, Laravel и Symfony, типичная ошибка и схема выбора. Версии сверены по Packagist 24.09.2026, примеры запущены на PHP 8.4.25.
Фреймворк, библиотека, CMS: в чем разница
Эти слова часто путают:
- Библиотека решает одну задачу, и ваш код сам ее вызывает (например, Monolog для логов или Guzzle для HTTP-запросов).
- Фреймворк задает структуру всего приложения и сам вызывает ваш код: вы пишете контроллер, а фреймворк решает, когда его запустить. Это и называют инверсией управления.
- Микрофреймворк дает только ядро: маршрутизацию, middleware и обработку ошибок. База данных, шаблоны и авторизация подключаются отдельными пакетами.
- CMS (WordPress, Drupal, Bitrix) — готовый продукт с админкой, который настраивают, а не пишут с нуля. Некоторые CMS построены на компонентах фреймворков: Drupal использует компоненты Symfony.
Все современные PHP-фреймворки ставятся через Composer — менеджер зависимостей PHP.
Сравнение популярных PHP-фреймворков
| Фреймворк | Тип | Актуальная версия (сентябрь 2026) | Нужен PHP | Работа с БД и шаблоны | Когда брать |
|---|---|---|---|---|---|
| Laravel | full-stack | 13.x (13.33.0) | 8.3+ | Eloquent ORM, Blade | веб-приложения и API, когда важна скорость разработки и готовая экосистема |
| Symfony | full-stack из компонентов | 8.1 (8.1.7); LTS-ветка 7.4 | 8.4.1+ для 8.1; 8.2+ для 7.4 | Doctrine ORM (отдельный пакет), Twig | долгоживущие корпоративные системы, строгая архитектура |
| Yii 2 | full-stack | 2.0.55 | 7.4+ (по composer.json) | ActiveRecord, PHP-шаблоны, генератор кода Gii | CRUD-приложения и админки, поддержка существующих проектов |
| CodeIgniter 4 | легкий full-stack | 4.7.4 | 8.2+ | модели и Query Builder, свои представления | небольшие сайты, простой вход, минимум «магии» |
| Slim | микрофреймворк | 4.15.3 | 7.4 — 8.5 | нет из коробки | REST API, микросервисы, прокладки между системами |
| Laminas MVC | full-stack из компонентов | 3.8.0, только исправления безопасности | 8.1 — 8.4 | laminas-db, свои представления | только поддержка проектов на Zend Framework; для нового кода проект советует Mezzio |
Как читать таблицу. «Нужен PHP» — это ограничение из composer.json конкретной версии пакета: на более старом PHP Composer просто не установит фреймворк. Точную текущую версию показывает composer show -a <пакет>.
Про Yii стоит знать отдельно: Yii 2 — зрелая и стабильная ветка, а Yii 3 вышел стабильным 31 декабря 2025 года как набор независимых пакетов с другой архитектурой, это не обновление «на месте», а переход с переписыванием. Zend Framework в 2019-2020 годах передан в Linux Foundation и переименован в Laminas. В июне 2025 года команда Laminas объявила laminas-mvc завершенным: новых функций не будет, только исправления безопасности до конца поддержки PHP 8.4 (31.12.2028), а преемником называет микрофреймворк Mezzio.
Один маршрут в трех фреймворках
Задача для сравнения: API GET /courses/{id} возвращает курс в JSON, для несуществующего курса отдает 404, а нецифровой id вообще не совпадает с маршрутом.
Slim: минимальный полный пример
Установка в пустой папке:
composer require slim/slim:^4.15 slim/psr7
mkdir public
Файл public/index.php:
<?php
declare(strict_types=1);
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;
require __DIR__ . '/../vendor/autoload.php';
$courses = [
1 => ['id' => 1, 'title' => 'PHP Basic'],
2 => ['id' => 2, 'title' => 'PHP Professional'],
];
$app = AppFactory::create();
$app->addRoutingMiddleware();
$app->addErrorMiddleware(false, true, true); // false = не показывать трассировку клиенту
// {id:[0-9]+} - маршрут совпадет только с цифрами
$app->get('/courses/{id:[0-9]+}', function (Request $request, Response $response, array $args) use ($courses) {
$id = (int) $args['id'];
if (!isset($courses[$id])) {
$response->getBody()->write(json_encode(['error' => 'not found']));
return $response->withStatus(404)->withHeader('Content-Type', 'application/json');
}
$response->getBody()->write(json_encode($courses[$id], JSON_UNESCAPED_UNICODE));
return $response->withHeader('Content-Type', 'application/json');
});
$app->run();
Запуск встроенным сервером PHP (только для разработки) и проверка:
php -S localhost:8080 -t public
curl -i http://localhost:8080/courses/1
Что вернул сервер в прогоне:
GET /courses/1 -> 200, {"id":1,"title":"PHP Basic"}
GET /courses/7 -> 404, {"error":"not found"}
GET /courses/abc -> 404, HTML-страница Slim (маршрут не совпал)
POST /courses/1 -> 405 Method Not Allowed, заголовок Allow: GET
Разбор. Маршрутизацию, код 405 с заголовком Allow и страницу ошибок Slim сделал сам — в чистом PHP это пришлось бы писать вручную. Ответ — неизменяемый объект по стандарту PSR-7: withStatus() и withHeader() возвращают новый объект, поэтому его обязательно нужно вернуть из обработчика. Если клиент присылает Accept: application/json, Slim отдает ошибку 404 в JSON: {"message": "404 Not Found"}.
Laravel: то же самое короче
После composer create-project laravel/laravel app маршрут добавляется в routes/web.php:
Route::get('/courses/{id}', function (int $id) {
$courses = [
1 => ['id' => 1, 'title' => 'PHP Basic'],
2 => ['id' => 2, 'title' => 'PHP Professional'],
];
abort_unless(isset($courses[$id]), 404);
return $courses[$id]; // массив Laravel сам превратит в JSON
})->where('id', '[0-9]{1,9}'); // не больше 9 цифр: число влезает в int
Проверено на Laravel Framework 13.33.0 через php artisan serve: /courses/1 отдает 200 и application/json, /courses/7 и /courses/abc — 404. Злой вход /courses/99999999999999999999 в первой версии с ->whereNumber('id') давал 500: строка из 20 цифр не помещается в int, и PHP бросает TypeError: Argument #1 ($id) must be of type int, string given. Ограничение длины в маршруте превращает такой запрос в 404. Slim и Symfony на этот вход отвечают 404 и без правки. Laravel прячет детали за соглашениями: возвращенный массив становится JSON-ответом, abort_unless() бросает HTTP-исключение.
Symfony: контроллер-класс и атрибут маршрута
После composer create-project symfony/skeleton app создается файл src/Controller/CourseController.php:
<?php
namespace App\Controller;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Attribute\Route;
final class CourseController
{
private const COURSES = [
1 => ['id' => 1, 'title' => 'PHP Basic'],
2 => ['id' => 2, 'title' => 'PHP Professional'],
];
#[Route('/courses/{id}', requirements: ['id' => '\d+'], methods: ['GET'])]
public function show(int $id): JsonResponse
{
if (!isset(self::COURSES[$id])) {
throw new NotFoundHttpException('Course not found');
}
return new JsonResponse(self::COURSES[$id]);
}
}
Проверено на Symfony 8.1.7: php bin/console debug:router показывает маршрут app_course_show GET /courses/{id}, ответы 200/404/404 те же, POST дает 405. Symfony многословнее, но все явно: тип ответа, ограничения маршрута и методы видны в самом коде.
Типичная ошибка: перенос привычек между фреймворками
Неверно — вернуть массив из обработчика Slim, как в Laravel:
$app->get('/courses/{id:[0-9]+}', function ($request, $response, array $args) {
return ['id' => (int) $args['id']];
});
Результат в прогоне: клиент получает 500 Internal Server Error с текстом Slim Application Error, а в лог сервера пишется:
Type: TypeError
Message: Slim\Handlers\Strategies\RequestResponse::__invoke(): Return value must be of type Psr\Http\Message\ResponseInterface, array returned
Исправление — записать JSON в тело ответа и вернуть объект Response, как в полном примере выше. Соглашения фреймворков различаются, код из документации одного нельзя копировать в другой без проверки.
Как выбрать PHP-фреймворк под задачу
| Задача | Что взять | Когда иначе |
|---|---|---|
| Первый проект, нужно быстро получить работающее приложение с авторизацией и БД | Laravel | если команда уже пишет на Symfony — учиться сразу на нем |
| Большая система на годы, несколько команд, строгие требования к архитектуре | Symfony (LTS-ветка) | для небольшого проекта Symfony может оказаться избыточным |
| Небольшой JSON API или микросервис | Slim | если понадобятся ORM, очереди и админка — проще сразу взять Laravel или Symfony |
| Простой сайт, слабый хостинг, минимум зависимостей | CodeIgniter 4 | при росте проекта проверить, хватает ли экосистемы пакетов |
| Поддержка существующего проекта | тот фреймворк, на котором он написан (часто Yii 2 или Laminas) | переписывание на другой фреймворк — отдельный проект с оценкой рисков |
Для вакансий в России чаще всего встречаются Laravel и Symfony, Yii 2 заметен в поддержке существующих проектов. Это наблюдение по рынку, а не правило: конкретный стек зависит от компании.
Безопасность: что фреймворк дает, а что нет
Фреймворк закрывает типовые дыры, но только если его не обходить. Blade и Twig по умолчанию экранируют вывод, ORM и Query Builder параметризуют запросы, в Laravel и Symfony есть защита форм от CSRF. Эта защита пропадает, если писать «сырой» SQL со склейкой строк или выводить данные без экранирования ({!! !!} в Blade, фильтр raw в Twig).
Три настройки, которые проверяют перед выкладкой. Первое: корнем веб-сервера должна быть папка public/, а не корень проекта, иначе .env с паролями может стать доступен по URL. Второе: режим отладки выключен (APP_DEBUG=false в Laravel, APP_ENV=prod в Symfony, displayErrorDetails = false в Slim). Третье: встроенный сервер php -S — только для разработки, в production используют nginx или Apache с PHP-FPM.
Если не получилось
- Composer отказывается ставить пакет и пишет про требование к версии php. Ваш PHP старше, чем нужно версии фреймворка (см. таблицу). Проверьте
php -vи обновите PHP либо выберите ветку, совместимую с вашей версией. - Любой URL, кроме главной, дает 404. Сервер запущен не из той папки: для Slim и Symfony нужен
-t public, для Laravel удобнееphp artisan serve. На nginx или Apache запросы должны перенаправляться вpublic/index.php. - Ошибка 500 без подробностей. Так и должно быть при выключенной отладке. Смотрите лог:
storage/logs/laravel.logв Laravel,var/log/в Symfony, stderr веб-сервера в Slim. - Class not found после добавления своего класса. Проверьте namespace и путь по PSR-4, затем выполните
composer dump-autoload.
Выводы
- Популярные PHP-фреймворки в 2026 году: Laravel 13 и Symfony 8 (с LTS-веткой 7.4) — основной выбор для новых проектов, Yii 2 и Laminas чаще встречаются в поддержке, CodeIgniter 4 — легкий вариант, Slim — микрофреймворк для API.
- Минимальная версия PHP различается: Laravel 13 требует PHP 8.3+, Symfony 8.1 — PHP 8.4.1+, это проверяется до выбора.
- Один и тот же маршрут в Laravel короче за счет соглашений, в Symfony явнее, в Slim виден весь цикл «запрос — ответ».
- Код между фреймворками не переносится напрямую: возврат массива работает в Laravel, но в Slim дает TypeError и ответ 500.
- Защита фреймворка работает, пока ее не обходят: сырой SQL, вывод без экранирования и включенная отладка на проде сводят ее на нет.
Где применяется / связь с практикой
Освойте тему на практике
Фреймворк — рабочий инструмент бэкенд-разработчика на PHP: на нем пишут интернет-магазины, личные кабинеты, внутренние сервисы компаний и API для мобильных приложений. Чтобы уверенно выбирать фреймворк, нужно понимать то, что под ним: HTTP, ООП, Composer, работу с базой данных и тестирование. Эти темы вместе с практикой на фреймворках разбирают на курсе «PHP-разработчик. Продвинутый уровень». Посмотреть формат занятий и задать вопросы преподавателям можно на открытых уроках Otus.
FAQ
Можно ли писать на PHP без фреймворка?
Да, для маленького скрипта или обучения это нормально. Но маршрутизацию, обработку ошибок, защиту форм и работу с БД тогда придется писать и поддерживать самому.
Что учить первым: Laravel или Symfony?
Обычно начинают с того, что чаще встречается в интересных вам вакансиях. Laravel быстрее дает результат, Symfony лучше показывает устройство приложения; многие компоненты Symfony используются внутри Laravel, поэтому знания частично переносятся.
Нужно ли знать чистый PHP перед фреймворком?
Да. Без понимания ООП, пространств имен, Composer и HTTP ошибки фреймворка выглядят как магия, а их диагностика превращается в угадывание.



