Помощники контроллера
Помощник контроллера (controller plugin) — небольшой класс с кодом, который нужен во многих действиях. Знакомые params(), redirect(), layout() и flashMessenger() — как раз такие помощники. Свой помощник избавляет от копирования одних и тех же строк из контроллера в контроллер.
Встроенные помощники
| Вызов в действии | Что делает |
|---|---|
$this->params() | Читает параметры запроса |
$this->redirect() | Перенаправляет |
$this->url()->fromRoute('blog') | Строит адрес по имени маршрута |
$this->layout() | Управляет макетом |
$this->forward()->dispatch(...) | Вызывает действие другого контроллера |
Свой помощник
Номер страницы из адреса нужен в каждом списке, и каждый раз его надо привести к числу не меньше единицы. Вынесем это в помощника. Создайте папку module/Blog/src/Controller/Plugin и файл в ней:
// module/Blog/src/Controller/Plugin/PageNumber.php
namespace Blog\Controller\Plugin;
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
class PageNumber extends AbstractPlugin
{
public function __invoke(): int
{
$page = (int) $this->getController()->params()->fromQuery('page', 1);
return max(1, $page);
}
}Класс наследует AbstractPlugin. Метод __invoke() выполняется при вызове помощника, а getController() возвращает контроллер, из которого его вызвали.
Регистрация
Помощников описывают в разделе controller_plugins файла module/Blog/config/module.config.php:
// module/Blog/config/module.config.php
'controller_plugins' => [
'factories' => [
Controller\Plugin\PageNumber::class => InvokableFactory::class,
],
'aliases' => [
'pageNumber' => Controller\Plugin\PageNumber::class,
],
],factories говорит, как создать класс, а aliases задаёт короткое имя — под ним помощник вызывают в действиях.
Вызов в действии
// module/Blog/src/Controller/PostController.php
public function indexAction()
{
$page = $this->pageNumber();
return new ViewModel(['page' => $page]);
}Для адреса /blog?page=3 в $page окажется 3, для /blog?page=-5 и /blog?page=abc — 1. Помощник доступен во всех контроллерах приложения, не только в модуле Blog.
Помощник с зависимостями
Помощнику можно передать сервисы через конструктор. Например, такой помощник возвращает вошедшего пользователя:
// module/Blog/src/Controller/Plugin/CurrentUser.php
namespace Blog\Controller\Plugin;
use Laminas\Authentication\AuthenticationService;
use Laminas\Mvc\Controller\Plugin\AbstractPlugin;
class CurrentUser extends AbstractPlugin
{
public function __construct(private AuthenticationService $auth) {}
public function __invoke(): ?array
{
return $this->auth->hasIdentity() ? $this->auth->getIdentity() : null;
}
}В настройках вместо InvokableFactory укажите ReflectionBasedAbstractFactory::class и добавьте псевдоним currentUser. В действии $this->currentUser() вернёт массив с id и email или null для гостя.
Частая ошибка
Если зарегистрировать помощника в factories, но забыть строку в aliases, вызов $this->pageNumber() закончится исключением о том, что помощник с таким именем не найден. Короткое имя не выводится из имени класса — его всегда задают псевдонимом.