Як працювати з передачами компілятора
Дата оновлення перекладу 2023-06-22
Як працювати з передачами компілятора
Передачі компілятора надають вам можливість проводити маніпуляції з іншими визначеннями сервісу, які були зареєстровані у сервіс-контейнері. Ви можете прочитати про те, як їх створити, у розділі компонента "".
Пропуски компілятора зареєстровані у методі 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 $containerBuilder): void
{
$containerBuilder->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 $containerBuilder): void
{
// у цьому методі ви можете робити маніпуляції з сервіс-контейнером:
// наприклад, змінити якийсь сервіс контейнера:
$containerBuilder->getDefinition('app.some_private_service')->setPublic(true);
// або обробити теговані сервіси:
foreach ($containerBuilder->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 $containerBuilder): void
{
parent::build($containerBuilder);
$containerBuilder->addCompilerPass(new CustomPass());
}
}
Якщо ви використовуєте користувацькі теги сервісу у
пакеті, тоді, за угодою, імена тегів складаються з імені пакету (нижній регістр, нижні
підкреслення в якості роздільників), за яким слідує крапка, і нарешті "справжнє" імʼя.
Наприклад, якщо ви хочете представити якийсь вид тегу "транспорту" у вашому AcmeMailerBundle,
вам слід назвати його acme_mailer.transport
.