Контроллеры и действия
Действие — класс, который принимает запрос и возвращает ответ. В Magento на каждый адрес приходится отдельный класс с единственным методом execute(). Слово «контроллер» здесь означает просто папку, в которой лежат родственные действия.
Где лежит действие
Адрес /hello/index/index ведёт к классу Controller/Index/Index.php модуля. Файл создают вручную.
app/code/Acme/Hello/
├── registration.php
├── Controller/
│ └── Index/
│ └── Index.php новый файл
└── etc/
├── module.xml
└── frontend/
└── routes.xmlПростое действие
// app/code/Acme/Hello/Controller/Index/Index.php
namespace Acme\Hello\Controller\Index;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
class Index implements HttpGetActionInterface
{
public function __construct(private ResultFactory $resultFactory) {}
public function execute(): ResultInterface
{
$result = $this->resultFactory->create(ResultFactory::TYPE_RAW);
$result->setContents('Привет из модуля!');
return $result;
}
}Откройте http://shop.test/hello — браузер покажет строку «Привет из модуля!» без оформления магазина. Интерфейс HttpGetActionInterface разрешает действию отвечать только на запросы GET; для отправки форм берут HttpPostActionInterface. Объект ResultFactory Magento передаёт в конструктор сам — как это работает, объясняет урок о внедрении зависимостей.
Виды результата
Метод execute() возвращает объект результата. Вид задаёт константа ResultFactory:
| Константа | Что возвращает |
|---|---|
TYPE_RAW | Произвольный текст |
TYPE_PAGE | Страницу магазина с шапкой и подвалом |
TYPE_JSON | Данные в формате JSON |
TYPE_REDIRECT | Перенаправление на другой адрес |
TYPE_FORWARD | Передачу запроса другому действию |
Страница магазина
Замените тело метода execute():
$page = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$page->getConfig()->getTitle()->set(__('Приветствие'));
return $page;По адресу /hello теперь открывается обычная страница магазина с заголовком «Приветствие» и пустой серединой. Чем её заполнить, расскажет урок о макетах. Функция __() делает строку переводимой.
Ответ JSON и параметры
Создайте второе действие — файл Controller/Index/Status.php:
// app/code/Acme/Hello/Controller/Index/Status.php
namespace Acme\Hello\Controller\Index;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Controller\ResultInterface;
class Status implements HttpGetActionInterface
{
public function __construct(
private ResultFactory $resultFactory,
private RequestInterface $request,
) {}
public function execute(): ResultInterface
{
$id = (int) $this->request->getParam('id');
return $this->resultFactory->create(ResultFactory::TYPE_JSON)
->setData(['status' => 'ok', 'id' => $id]);
}
}Адрес /hello/index/status/id/5 вернёт {"status":"ok","id":5}. Метод getParam() читает параметр и из адреса, и из строки запроса; второй аргумент — значение по умолчанию.
Перенаправление
return $this->resultFactory->create(ResultFactory::TYPE_REDIRECT)->setPath('hello');Посетитель попадёт на страницу /hello. В setPath() передают путь в том же виде, что и в getUrl().
Частая ошибка
Страница отдаёт 404, хотя класс написан. Проверьте три вещи: пространство имён совпадает с путём к файлу, папка называется Controller в единственном числе, а регистр букв в именах папок и файла точно такой же, как в классе. На Windows ошибка в регистре не заметна, а на сервере с Linux файл не будет найден.