Контроллеры и действия в Yii 2: короткое руководство
Как создать контроллер в Yii 2, объявить действия, вернуть JSON и настроить фильтры доступа. Разбираем на рабочих примерах — от маршрута до проверки в браузере.

За полчаса вы создадите контроллер в Yii 2.0.x, объявите в нём действия, вернёте HTML-страницу и JSON, а в конце ограничите доступ по ролям через фильтр. Всё на чистом фреймворке, без Gii-генератора — чтобы понимать, что именно вы пишете.
Перед началом убедитесь, что у вас установлено: PHP 7.4 или новее (Yii 2.0.49+ работает и на PHP 8.1), сам фреймворк через Composer (composer create-project yiisoft/yii2-app-basic), веб-сервер настроен на каталог web/, а базовый URL проекта открывается в браузере. Мы работаем с шаблоном basic — не advanced. В advanced-шаблоне пути к контроллерам другие (frontend/controllers, backend/controllers), но синтаксис самих классов идентичен.
Что такое контроллер и действие в терминах Yii
Контроллер — это PHP-класс, наследник yii\web\Controller. Он принимает запрос, вызывает нужную логику и возвращает ответ. Действие (action) — это то, что реально отрабатывает конкретный URL. Действие бывает двух видов: метод класса с префиксом action и отдельный класс-действие. Начнём с первого — он покрывает 90% задач.
Роутинг* * Роутинг — сопоставление URL входящему запросу с конкретным контроллером и действием. В Yii по умолчанию адрес /site/about означает контроллер SiteController и действие actionAbout.
Первый контроллер
Создайте файл controllers/HelloController.php. Имя файла и класса — в CamelCase, с суффиксом Controller.
<?php
// controllers/HelloController.php — Yii 2.0.x
namespace app\controllers;
use yii\web\Controller;
class HelloController extends Controller
{
// Действие по умолчанию, вызывается при /hello
public function actionIndex()
{
return $this->render('index');
}
// Действие /hello/say
public function actionSay($message = 'мир')
{
// Параметр message придёт из query-строки: /hello/say?message=Yii
return $this->render('say', ['message' => $message]);
}
}
Метод actionSay ждёт представление. Создайте views/hello/say.php:
<?php
// views/hello/say.php
use yii\helpers\Html;
?>
<h1>Привет, <?= Html::encode($message) ?></h1>
Проверка: откройте /index.php?r=hello/say&message=Yii (или /hello/say?message=Yii, если включён красивый URL). В браузере появится «Привет, Yii». Если убрать параметр — «Привет, мир»: сработает значение по умолчанию из сигнатуры метода.
Как имя метода превращается в URL
Yii берёт имя действия из части метода после action и переводит CamelCase в написание через дефис. Метод actionCreatePost отвечает на URL /hello/create-post, а не /hello/createPost. Это частый источник ошибки «404» у новичков.
Возврат JSON вместо страницы
Действие не обязано рендерить HTML. Чтобы отдать JSON, переключите формат ответа. Правильный способ — задать Response::format, тогда Yii сам сериализует возвращённый массив.
<?php
// В том же HelloController
use Yii;
use yii\web\Response;
public function actionApi()
{
// Переключаем формат ответа на JSON
Yii::$app->response->format = Response::FORMAT_JSON;
return [
'status' => 'ok',
'items' => [1, 2, 3],
];
}
Проверка: откройте /hello/api. Заголовок Content-Type будет application/json, тело — {"status":"ok","items":[1,2,3]}. Массив превращать в JSON вручную через json_encode не нужно — этим займётся форматтер ответа.
Возвращайте из действия данные, а не готовый вывод. Печатать через echo внутри действия — прямой путь к сломанным заголовкам и невозможности переключить формат ответа.Отдельный класс-действие
Если одно и то же действие нужно в нескольких контроллерах — например, «капча» или «выход» — вынесите его в отдельный класс и подключите через метод actions(). Yii поставляется с несколькими такими действиями «из коробки».
<?php
// В контроллере
public function actions()
{
return [
// Стандартное действие капчи
'captcha' => [
'class' => 'yii\\captcha\\CaptchaAction',
],
// Стандартный обработчик ошибок
'error' => [
'class' => 'yii\\web\\ErrorAction',
],
];
}
Точные имена классов действий и их параметры смотрите в официальной документации Yii — они могут отличаться в зависимости от установленных расширений.
Метод-действие или класс-действие: что выбирать
| Критерий | Метод actionX | Отдельный класс |
|---|---|---|
| Логика уникальна для контроллера | Да | Избыточно |
| Действие переиспользуется | Копипаст | Да |
| Много зависимостей и настроек | Метод раздувается | Аккуратнее |
| Скорость написания | Быстрее | Больше кода |
Начинайте с методов. Выносите в класс, когда действие понадобилось в третьем контроллере или разрослось настолько, что тело метода перестаёт читаться целиком.
Ограничение доступа фильтром
Контроллер редко бывает полностью открытым. Доступ по ролям и статусу авторизации задаёт поведение AccessControl в методе behaviors().
<?php
use yii\filters\AccessControl;
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::class,
'only' => ['api'], // фильтр действует только на actionApi
'rules' => [
[
'allow' => true,
'roles' => ['@'], // только авторизованным
],
],
],
];
}
Проверка: откройте /hello/api из-под гостя. Вместо JSON Yii перенаправит на страницу входа или отдаст 403 — в зависимости от того, задан ли loginUrl в конфиге компонента user. Символ @ означает «авторизованный пользователь», ? — «гость».
Если не получилось
- «Unable to resolve the request … hello/say» — Yii не нашёл действие. Проверьте, что метод называется именно
actionSay(с большой S) и класс лежит в неймспейсеapp\controllers. - 404 на
/hello/create-post, хотя метод есть — вы, вероятно, назвали URL какcreatePost. Yii ждёт дефис, а не camelCase в адресе. - JSON приходит как обычный текст или ломается вёрстка — вы печатаете через
echoили забыли строку сResponse::FORMAT_JSON. Возвращайте массив черезreturn. - «Class "app\controllers\HelloController" not found» — не совпадает имя файла и класса либо неверный неймспейс. Файл должен называться
HelloController.php. - Фильтр доступа не срабатывает — метод называется
behaviors()без опечаток, а имя действия вonlyнаписано без префиксаactionи в нижнем регистре (api, неactionApi).
Что дальше
Следующий шаг после контроллера — научить действие получать данные из формы через модель (yii\base\Model и метод $model->load(Yii::$app->request->post())) и понять, как настроить красивые URL через компонент urlManager с enablePrettyUrl. Правила маршрутизации — отдельная большая тема, здесь мы касались только дефолтного роутинга. Если строите API — посмотрите в сторону yii\rest\Controller, он избавляет от ручного переключения формата ответа и даёт CRUD-действия почти без кода.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: Yii 2.0 Guide — Controllers, Yii 2.0 Guide — Access Control Filter
Частые вопросы
У меня advanced-шаблон, а не basic. Код подойдёт?
Почему URL /hello/createPost выдаёт 404, а метод actionCreatePost есть?
Обязательно ли создавать представление для каждого действия?
Работает ли это на PHP 8?
Что если фильтр AccessControl не пускает даже авторизованного пользователя?
Можно ли в одном действии и рендерить HTML, и иногда отдавать JSON?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.