Як працювати з пропусками компілятора
Дата оновлення перекладу 2022-11-25
Як працювати з пропусками компілятора
Пропуски компілятора надають вам можливість проводити маніпуляції з іншими визначеннями сервісу, які були зареєстровані у сервіс-контейнері. Ви можете прочитати про те, як їх створити, у розділі компонента "".
Пропуски компілятора зареєстровані у методі 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 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
.