Я очень новичок в среде Symfony, и я пытаюсь повторить то, что я обычно делаю с другими языками (все еще следуя шаблону MVC)
Цель состоит в том, чтобы вызывать InitializeSomething() каждый раз, когда вызывается Fly(), непосредственно перед этим. Вот мой код:
<?php
// src/Controller/ExampleController.php
namespace App\Controller;
use App\Common\Utils;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class ExampleController extends BaseController
{
public function __construct()
{
// Initialize vars and so on...
}
/**
* @Route("/example/fly")
*/
public function Fly()
{
// This method is obviously called via the route
}
private function InitializeSomething()
{
// I would like to call this before Fly() is executed
}
...
Конечно, самый простой способ достичь результата:
...
/**
* @Route("/example/fly")
*/
public function Fly()
{
$this->InitializeSomething();
...
}
...
Если нет другого элегантного способа сделать это, я выберу это решение, я просто хотел бы избежать распространения по всему моему коду одного и того же метода везде (конечный дом для метода InitializeSomething будет в базовом классе).
Обычно с другими языками я просто вызываю свой InitializeSomething внутри конструктора, потому что классы контроллера создаются каждый раз, когда вызывается метод, но здесь, кажется, Symfony работает по-другому, и когда вызывается конструктор, слишком рано выполнять мою инициализацию.
Ред.: Спасибо за советы! Вот несколько примеров того, что я собираюсь сделать.
private function InitializeSomething()
{
// Add the connection to a local variable, just to have a shortcut and avoid boilerplate
$this->dbconnection = $this->getEntityManager()->getConnection();
$this->dbengine = $this->getDoctrine();
// Engine start
if($engine==false) {
SwitchOnEngine();
}
if($engine->rpm < 1000) {
WaitEngineStart();
}
// Other things like logging the event and so on
}
Дело в том, что если я забуду инициализировать вещи, произойдет что-то неправильное, и я хочу свести к минимуму ошибки, позволив машине инициализировать вещи автоматически, один раз для каждого класса.
1 ответ
В Symfony есть то, что мы называем Событиями. Вы можете проверить документацию, но это конкретное событие здесь вызывается прямо перед выполнением контроллера: https://symfony.com/doc/current/reference/ events.html#kernel-controller-arguments
Здесь у вас есть полная документация о компоненте событий Symfony, чтобы вы могли понять, как реализовать то, что вам нужно: https://symfony.com/doc/current/event_dispatcher.html
Вы получите что-то вроде:
class InitializerListener
{
public function onKernelController(ControllerEvent $event)
{
[$controllerInstance, $actionName] = $this->getController();
$controllerInstance->initializeSomething();
}
}
И в вашем конфиге:
# config/services.yaml
services:
App\EventListener\InitializerListener:
tags:
- { name: kernel.event_listener, event: kernel.controller }
PS.: Если ваш контроллер имеет более одного метода действия, getController
возвращает массив в формате, показанном в приведенном выше коде. См.: https://symfony.com/doc/current/event_dispatcher/before_after_filters.html< /а>
Кроме того, не начинайте свои методы с заглавных букв в PHP: https://www.php-fig.org/psr/psr-12/< /а>
Похожие вопросы
Новые вопросы
php
PHP — это широко используемый язык сценариев общего назначения с открытым исходным кодом, мультипарадигмальный, динамически типизированный и интерпретируемый, изначально разработанный для веб-разработки на стороне сервера. Используйте этот тег для вопросов о программировании на языке PHP.
controller_arguments
. Вы также можете вызвать метод после создания...AbstractController
, возможно, он вообще не использует локатор, поэтому я попросил больше подробностей и указал разные варианты. Но ваша точка зрения верна.InitializeSomething
? Один-два примера были бы очень полезны. Также было бы полезно назвать один или два фреймворка/проекта MVC, которые применяют такой «трюк», чтобы мы могли провести небольшое целенаправленное исследование по этому вопросу. В любом случае инициализация/назначение должны происходить либо в конструкторе, либо в самом действии контроллера (Fly
).