Как работать с передачами компилятора
Дата обновления перевода 2025-02-15
Как работать с передачами компилятора
Передачи компилятора предоставляют вам возможность проводить манипуляции с другими определениями сервиса, которые были зарегистрированы в сервис-контейнере.
Если ваша передача компилятора относительно небольшая, вы можете определить ее внутри класса приложения
Kernel
вместо того, чтобы создавать отдельный класс передачи компилятора .
Для этого заставьте ваше ядро реализовывать 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()
:
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
// src/MyBundle/MyBundle.php
namespace App\MyBundle;
use App\DependencyInjection\Compiler\CustomPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
class MyBundle extends AbstractBundle
{
public function process(ContainerBuilder $container): void
{
// в этом методе вы можете манипулировать сервис-контейнером:
// например, изменение какого-то сервис-контейнера:
$container->getDefinition('app.some_private_service')->setPublic(true);
// или обработка тегированного сервиса:
foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
// ...
}
}
}
Альтернативно, при использовании отдельных классов передачи компилятора ,
пакеты могут включить их в методе build()
своего главного класса пакета:
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\AbstractBundle;
class MyBundle extends AbstractBundle
{
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new CustomPass());
}
}
Если вы используете пользовательские теги сервиса в
пакете, тогда, по соглашению, имена тегов состоят из имени пакета (нижний регистр, нижние
подчеркивания в качестве разделителей), за которым следует точка, и, наконец, "настоящее" имя.
Например, если вы хотите представить какой-то вид тега "транспорту" в вашем AcmeMailerBundle,
вам следует назвать его acme_mailer.transport
.