Вызовите другой метод непосредственно перед вызовом метода по маршруту в Symfony - PullRequest
1 голос
/ 14 апреля 2020

Я очень новичок в Symfony framework и пытаюсь повторить то, что я обычно делаю, с другими языками (все еще следуя шаблону 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();
      ...
    }
...

Если нет другого элегантного способа сделать это, я go для этого решения я просто хотел бы избежать повсеместного распространения по всему коду одного и того же метода (последний дом для метода InitializeSomething будет в базовом классе).

Обычно с другими языками, которые я просто вызываю my InitializeSomething внутри конструктора, потому что классы контроллеров создаются каждый раз, когда вызывается метод, но здесь кажется, что Symfony работает по-другому, и когда конструктор вызывается слишком рано, чтобы выполнить мою инициализацию.

Edit: Спасибо за ваши советы! Вот несколько примеров того, что я собираюсь сделать.

    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 Ответ

1 голос
/ 14 апреля 2020

Symfony имеет то, что мы называем событиями. Вы можете проверить документацию, но это конкретное c событие здесь вызывается непосредственно перед выполнением контроллера: 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:

# 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/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...