Контроллеры в Laravel: с чего начать новичку
За полчаса разберём, как создать контроллер в Laravel 11, связать его с маршрутом и вернуть ответ. От artisan-команды до первой рабочей страницы с проверками на каждом шаге.

К концу этого разбора у вас будет работающий контроллер, который отвечает на запрос по адресу вроде /posts и возвращает данные. Займёт минут двадцать-тридцать, если Laravel уже установлен. Всё написано для Laravel 11.x (актуальная ветка на момент написания) — в более старых версиях отличается расположение файла маршрутов и синтаксис их регистрации, об этом скажу отдельно.
Что нужно иметь до начала
Прежде чем создавать первый контроллер, убедитесь, что у вас есть:
- PHP 8.2 или выше — минимальная версия для Laravel 11. Проверьте командой
php -v. - Composer — менеджер зависимостей PHP. Проверьте
composer --version. - Развёрнутый проект Laravel 11. Если его нет, создайте:
composer create-project laravel/laravel my-app. - Запущенный сервер разработки: из папки проекта выполните
php artisan serve. Приложение поднимется наhttp://127.0.0.1:8000.
Все команды artisan выполняются из корня проекта — той папки, где лежит файл artisan.
Что такое контроллер и зачем он
Контроллер* — это класс, который принимает HTTP-запрос и решает, что на него ответить: отдать HTML-страницу, JSON или редирект. Логику можно писать прямо в файле маршрутов, но при десятке-другом адресов он превращается в кашу. Контроллеры разносят обработчики по классам и методам.
* HTTP-запрос — обращение браузера или другого клиента к вашему серверу: например, открытие страницы или отправка формы. Контроллер — точка, где вы решаете, что вернуть в ответ.
Шаг 1. Создаём контроллер
Выполните в терминале:
php artisan make:controller PostController
Проверка: в консоли появится строка INFO Controller [app/Http/Controllers/PostController.php] created successfully., а в папке app/Http/Controllers — новый файл.
Откройте его. Внутри будет пустой класс:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
//
}
Шаг 2. Добавляем метод
Метод контроллера — это и есть обработчик запроса. Добавьте метод index, который вернёт простой текст:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PostController extends Controller
{
// Отдаёт список постов
public function index()
{
return 'Список постов';
}
}
Пока метод возвращает строку — Laravel сам обернёт её в HTTP-ответ. Позже здесь появится обращение к базе и шаблон.
Шаг 3. Связываем метод с маршрутом
Метод сам по себе не вызовется — нужно указать, по какому адресу он отвечает. В Laravel 11 веб-маршруты живут в файле routes/web.php. Откройте его и добавьте:
<?php
use App\Http\Controllers\PostController;
use Illuminate\Support\Facades\Route;
Route::get('/posts', [PostController::class, 'index']);
Строка use App\Http\Controllers\PostController; обязательна — без неё PHP не найдёт класс. Первый аргумент Route::get — адрес, второй — массив из имени класса и названия метода.
Проверка: откройте в браузере http://127.0.0.1:8000/posts. На странице должно появиться «Список постов». Если сервер не запущен — выполните php artisan serve.
В Laravel 8 и раньше маршрут можно было записать строкой 'PostController@index'. С Laravel 8 рекомендован синтаксис с массивом и ::class — используйте его.
Шаг 4. Передаём данные в шаблон
Возвращать голую строку скучно. Отдадим HTML через шаблон Blade. Создайте файл resources/views/posts.blade.php:
<h1>Посты</h1>
<ul>
@foreach ($posts as $post)
<li>{{ $post }}</li>
@endforeach
</ul>
Теперь измените метод index, чтобы он передал в шаблон массив:
public function index()
{
$posts = ['Первый пост', 'Второй пост', 'Третий пост'];
return view('posts', ['posts' => $posts]);
}
Функция view первым аргументом принимает имя файла без расширения .blade.php, вторым — массив данных для шаблона.
Проверка: обновите /posts — увидите заголовок «Посты» и маркированный список из трёх строк.
Шаг 5. Принимаем параметр из URL
Добавим страницу одного поста по адресу вроде /posts/5. Сначала маршрут в routes/web.php:
Route::get('/posts/{id}', [PostController::class, 'show']);
Фигурные скобки означают параметр. Его значение прилетит в одноимённый аргумент метода. Добавьте метод show:
// Отдаёт один пост по его идентификатору
public function show(string $id)
{
return "Открыт пост №{$id}";
}
Проверка: откройте /posts/42 — увидите «Открыт пост №42». Порядок маршрутов имеет значение: если статичный /posts/create нужен вместе с /posts/{id}, объявляйте статичный выше.
Контроллер — это не место для бизнес-логики целиком. Его задача — принять запрос, вызвать нужное и вернуть ответ. Как только внутри метода набирается тридцать строк расчётов, их пора выносить в отдельный класс.
Ресурсный контроллер: семь методов сразу
Для типичного CRUD (создать, показать, изменить, удалить) Laravel умеет генерировать заготовку со всеми методами:
php artisan make:controller PostController --resource
В классе появятся методы index, create, store, show, edit, update, destroy. Зарегистрировать все маршруты к ним можно одной строкой:
Route::resource('posts', PostController::class);
Какой метод за что отвечает:
| HTTP-метод | Адрес | Метод контроллера | Назначение |
|---|---|---|---|
| GET | /posts | index | список |
| GET | /posts/create | create | форма создания |
| POST | /posts | store | сохранить новый |
| GET | /posts/{id} | show | показать один |
| GET | /posts/{id}/edit | edit | форма редактирования |
| PUT/PATCH | /posts/{id} | update | обновить |
| DELETE | /posts/{id} | destroy | удалить |
Проверить, какие маршруты реально зарегистрированы, поможет команда php artisan route:list.
Если не получилось
- 404 Not Found на /posts. Маршрут не зарегистрирован или в файле опечатка. Выполните
php artisan route:list— если строки с/postsнет, проверьтеroutes/web.php. Иногда помогает сбросить кеш маршрутов:php artisan route:clear. - Class "App\Http\Controllers\PostController" not found. Забыли строку
use App\Http\Controllers\PostController;вверху файла маршрутов либо неверно указали namespace в самом контроллере. - View [posts] not found. Файл шаблона лежит не там или назван иначе. Он должен быть
resources/views/posts.blade.php, а вview()имя пишется без.blade.php. - Undefined variable $posts. В шаблон не передали переменную. Проверьте, что во втором аргументе
view()есть ключ'posts'. - Страница пустая или белый экран. Загляните в
storage/logs/laravel.log— там будет текст ошибки. В режиме отладки (переменнаяAPP_DEBUG=trueв файле.env) Laravel показывает трассировку прямо в браузере.
Что делать дальше
Контроллер, отдающий заранее заданный массив, — только каркас. Следующие шаги, чтобы он стал рабочим:
- Подключите базу данных и модель Eloquent, чтобы
indexдоставал реальные посты вместо статичного массива. - В методе
storeдобавьте валидацию входящих данных через$request->validate([...])— не доверяйте тому, что прислал браузер. - Разберитесь с Form Request — отдельным классом для правил валидации, чтобы не раздувать методы контроллера.
Инъекция зависимостей в методы и вынос логики в сервисные классы — отдельная тема, здесь мы разобрали только базовую связку «маршрут — контроллер — ответ».
Проверка грамотности: Орфография, пунктуация, стиль — с объяснением каждой правки
Спросить за 10 ₽Источники: Laravel 11 — Controllers (официальная документация), Laravel 11 — Routing (официальная документация)
Частые вопросы
У меня Laravel 10, синтаксис из статьи подойдёт?
Маршрут добавил, но всё равно 404 — что делать?
Где лучше писать код — в контроллере или в маршруте?
Обязательно ли наследовать контроллер от базового Controller?
Чем ресурсный контроллер лучше обычного?
Как посмотреть все зарегистрированные маршруты?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.