Як працювати з передачами компілятора
Дата оновлення перекладу 2025-01-17
Як працювати з передачами компілятора
Передачі компілятора надають вам можливість проводити маніпуляції з іншими визначеннями сервісу, які були зареєстровані у сервіс-контейнері.
Якщо ваша передача компілятора відносно невелика, ви можете визначити її всередині класу
класу додатку 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) {
// ...
}
}
}
Альтернативно, при використанні :ref:1e4f440fd4cc46b7f0953c86b02c40a391999a3ebuild()`` свого головного класу пакета:
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
.