Как работать с передачами компилятора в пакетах
Дата обновления перевода 2023-06-30
Как работать с передачами компилятора в пакетах
Передачи компилятора предоставляют вам возможность производить манипуляции с другими определениями сервиса, которые были зарегистрированы в сервис-контейнере. Вы можете прочитать о том, как создать их в разделе компоненты "".
Compiler passes are registered in the build()
method of the application kernel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// src/Kernel.php
namespace App;
use App\DependencyInjection\Compiler\CustomPass;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
class Kernel extends BaseKernel
{
use MicroKernelTrait;
// ...
protected function build(ContainerBuilder $container): void
{
$container->addCompilerPass(new CustomPass());
}
}
Одним из наиболее распространенных случаев использования передач компилятора является
работа с тегированными сервисами. В таких случаях, вместо
создания передачи компилятора, вы можете сделать так, чтобы ядро реализовывало
CompilerPassInterface и
обработать сервисы внутри метода process()
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// src/Kernel.php
namespace App;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
// ...
public function process(ContainerBuilder $container): void
{
// в этом методе вы можете изменять сервис-контейнер:
// например, изменить какой-то сервис-контейнер:
$container->getDefinition('app.some_private_service')->setPublic(true);
// или обработать тегированные сервисы:
foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
// ...
}
}
}
Работа с передачами компилятора в пакетах
Пакеты могут определять передачи компилятора в методе build()
главного класса пакета (это не нужно при реализации метода process()
в расширении):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
// src/MyBundle/MyBundle.php
namespace App\MyBundle;
use App\DependencyInjection\Compiler\CustomPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class MyBundle extends Bundle
{
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new CustomPass());
}
}
Если вы используете пользовательские сервис-теги в
пакете, тогда, по соглашению, имена тегов состоят из имени пакета (нижний регистр,
нижние подчеркивания в качестве разделителей), за которым следует точка, а затем
"настоящее" имя. Например, если вы хотите представить некоторый тег "транспорта" в
вашем AcmeMailerBundle, вы должны назвать его acme_mailer.transport
.