Контроллер базового класса с глобальной службой twig

Прежде всего, я должен сказать, что я уже несколько дней вижу ответы и документацию, но ни один из них не отвечает на мой вопрос.

Единственное и простое, что я хочу сделать, - это использовать службу twig как глобальную службу в BaseController.

Это мой код:

<?php
namespace App\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use App\Service\Configuration;
use App\Utils\Util;


abstract class BaseController extends Controller
{

    protected $twig;
    protected $configuration;

    public function __construct(\Twig_Environment $twig,Configuration $configuration)
  {
    $this->twig = $twig;
    $this->configuration = $configuration;
  }

}

Затем во всех моих контроллерах расширьте службу ветки и конфигурации, не вводя ее снова и снова.

//...
//......

/**
 * @Route("/configuration", name = "configuration_")
 */
class ConfigurationController extends BaseController
{

    public function __construct()
    {
       //parent::__construct();

       $this->twig->addGlobal('menuActual', "config");

    }

Как видите, единственное, что я хочу, - это иметь какой-то глобальный services, чтобы все было более организовано, а также создать глобальный shortcuts для всех моих controllers. В этом примере я назначаю глобальную переменную, чтобы сделать ссылку активной в меню моего шаблона, и в каждом контроллере мне нужно добавить новое значение для menuActual, например, в UserController переменной будет addGlobal('menuActual', "users").

Я думаю, это должно быть в хороших практиках symfony, которых я не нахожу :(.

Мне кажется, что необходимость включать \Twig_Environment в каждый контроллер для присвоения переменной представлению очень часто. Это должно быть по умолчанию в контроллере.

Спасибо

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
2
0
411
1

Ответы 1

У меня тоже была эта проблема - я пытался не повторять немного кода для каждого контроллера / действия.

Я решил это с помощью прослушивателя событий:

# services.yaml
app.event_listener.controller_action_listener:
    class: App\EventListener\ControllerActionListener
    tags:
        - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
#src/EventListener/ControllerActionListener.php
namespace App\EventListener;

use App\Controller\BaseController;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

/**
 * Class ControllerActionListener
 *
 * @package App\EventListener
 */
class ControllerActionListener
{
    public function onKernelController(FilterControllerEvent $event)
    {
        //fetch the controller class if available
        $controllerClass = null;
        if (!empty($event->getController())) {
            $controllerClass = $event->getController()[0];
        }

        //make sure your global instantiation only fires if the controller extends your base controller
        if ($controllerClass instanceof BaseController) {
            $controllerClass->getTwig()->addGlobal('menuActual', "config");
        }
    }
}

Спасибо. Да, обнаружил, что у меня проблема в том, что в каждом контроллере мне нужно добавить новое значение для menuActual, например, в UserController переменная будет addGlobal('menuActual', "users"), поэтому ваш пример не решит мою проблему полностью

jcarlosweb 11.06.2018 10:45

Вы можете установить свойство или метод в классах, которые расширяют BaseController для обработки специфической части класса. Затем прослушиватель событий использует / вызывает это для его запуска. Если вы используете метод, вы можете определить его как абстрактный в базовом контроллере, чтобы обеспечить его определение расширяющимися классами.

Bananaapple 11.06.2018 11:00

Это отличная идея, позвольте мне попробовать, и если у меня возникнут вопросы, я дам вам знать. Большое спасибо.

jcarlosweb 11.06.2018 11:03

в конце концов, это то же самое, или я думаю, что не знаю, потому что мне нужно везде добавлять \Twig_Environment $twig, а также в listener$controllerClass->setTwig() запрашивает у меня параметр веточки :(

jcarlosweb 11.06.2018 12:01

Вы не должны этого делать - какой бит это конкретно динамический, основанный на контроллерах? имя и значение переменной, которые входят в addGlobal()?

Bananaapple 11.06.2018 13:43

Да, именно в каждый контроллер я должен добавить имя и новое значение, как в конструкциях, так и в различных функциях контроллера, если это необходимо. Я предполагаю, что у конструктора каждого контроллера нет другого выхода, кроме как снова ввести ветку, верно? Простите за вопросы, но мне нужно понять.

jcarlosweb 11.06.2018 22:09

Ладно, я тупой, это не имеет ничего общего с Symfony, и я думаю, это PHP. В PHP в конструкциях вам нужно снова передать службы, чтобы перезаписать их в BaseController или в родительском классе. Если нет, вы не сможете его использовать, то в методах вам действительно не нужно использовать конструкторы и вы можете без проблем получить доступ к $ this-> twig.

jcarlosweb 12.06.2018 05:09

Я собираюсь дать ваш ответ как правильный, поскольку он также помог мне создать общее событие для всех контроллеров. Искренне благодарю вас и прости за мою неопытность.

jcarlosweb 12.06.2018 05:18

Вам не нужно снова передавать службу - вы могли бы определить protected $twig в базовом контроллере, а затем назначить этот экземпляр \Twig_Environment в прослушивателе событий ...

Bananaapple 12.06.2018 08:46

Это не работает для конструктора, да для методов, но не для конструктора, для конструктора служба должна быть повторно введена. Вы можете привести мне пример? Это слушатель pastebin.com/xbzLsiMv Тогда в контроллере pastebin.com/2FzXieS2 ошибка Call to a member function addGlobal() on null

jcarlosweb 12.06.2018 10:43

Не могли бы вы привести мне пример?

jcarlosweb 12.06.2018 23:54

Другие вопросы по теме