Добавить данные во все контроллеры
Дано: n-ное количество контроллеров и переменная, которая тянется сервисом из базы данных, и которая нужна всем этим контроллерам.
Суть вопроса: как "прокинуть" переменную во все контроллеры, не прокидывая каждый раз в них сервис.
Пример контроллера:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Doctrine\Persistence\ManagerRegistry;
use Knp\Component\Pager\PaginatorInterface;
...
class FooController extends AbstractController
{
private $doctrine;
private $paginator;
public function __construct(ManagerRegistry $doctrine, PaginatorInterface $paginator)
{
...
}
/**
* @Route("/foo", name="foo")
*/
public function index(Request $request): Response
{
$qb = $this->doctrine->getRepository(Foo::class)->function();
$page = $request->query->get('aaa', 1);
...
return $this->render('default/foo.twig', [
]);
}
/**
* @Route("/foo/{url}", name="foo_bar")
*/
public function fooBar(Request $request, string $baz): Response
{
$co = new Co();
$foo = $this->doctrine->getRepository(Co::class)->function(['baz' => $baz]);
...
return $this->renderForm('aaa/foo_bar.twig', [
]);
}
}
Пример сервиса
<?php
namespace App\Servise;
use App\Repository\FooRepository;
use Symfony\Component\DependencyInjection\ContainerInterface;
class FooServise
{
private $foo;
private $bar;
private $baz;
public function __construct(FooRepository $repository, ContainerInterface $container)
{
$this->foo = $repository;
$this->bar = $repository->findAll();
$this->baz = current(array_filter(
$this->bar,
function($bar)
{
return $bar->getName() === 'aaaaa';
}))->getValue();
}
...
public function Bar(): string
{
return $this->baz;
}
...
}
Так вот. Можно ли как-то "прокинуть" baz переменную сразу во все контроллеры? Подключать в каждый контроллер сервис не хочется. Подкиньте идеи, будьте добры
UPDATE
Переменная нужна не для вывода в шаблоны, а для использования внутри контроллеров. Копаю в сторону EventSubscriber, но как-то застрял на месте, как бы такое реализовать
Ответы (2 шт):
Накопал в документации Creating an Event Listener
Глянул таблицу, оказалось, что копать нужно было не в сторону RequestEvent, а в сторону KernelEvent. Навесил EventSubscriber на событие ядра:
<?php
namespace App\EventSubscriber;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use App\Servise\FooServise;
class KernelEventSubscriber implements EventSubscriberInterface
{
private $foo;
public function __construct(FooServise $foo)
{
$this->foo = $foo;
}
public function onKernelRequest(KernelEvent $event)
{
$event->getRequest()->request->add(['baz' => $this->foo->Bar()]);
}
public static function getSubscribedEvents()
{
return [
'kernel.request' => 'onKernelRequest',
];
}
}
Теперь получаем в контроллере переменную через Request:
$request->request->get('baz');
Возможно что это самое хорошее решение. Я бы не стал закидывать в request кастомный параметр, мы ведь ожидаем в request то что к нам приходит, простите, в реквесте, а тут мы имеем магию в виде baz... и не говоря о том что в момент когда все об этом забудбут, кто то будет удивлятся почему baz из реквеста какой то постоянно не тот.
Ну и даже если вы решили всю свою бизнес логику и работу с БД выполнять в контроллере, то вам скорее стоит присмотреться все же к https://symfony.com/doc/current/controller/argument_value_resolver.html кастомному резолверу. И то у меня большие сомнения верно ли вы выстроили работу с данными архитектурно, ведь
Переменная нужна не для вывода в шаблоны, а для использования внутри контроллеров.
немного сбивает с толку. Если вам для работы контроллера нужны данные завязаны на данных из базы данных, то очень большой риск что вы контроллер используете не совсем по назначению.