如何使用编译器 Pass
编译器 pass 使您有机会操作已在服务容器中注册的其他服务定义。
如果你的编译器 pass 相对较小,你可以将其定义在应用程序的 Kernel
类中,而不是创建一个单独的编译器 pass 类。
为此,请使你的内核实现 CompilerPassInterface 并在 process()
方法中添加编译器 pass 代码
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
{
// in this method you can manipulate the service container:
// for example, changing some container service:
$container->getDefinition('app.some_private_service')->setPublic(true);
// or processing tagged services:
foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
// ...
}
}
}
如果你创建单独的编译器 pass 类,请在应用程序内核的 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());
}
}
在扩展包中使用编译器 Pass
如果你的编译器 pass 相对较小,你可以直接在主扩展包类中添加它。为此,请使你的扩展包实现 CompilerPassInterface 并将编译器 pass 代码放在主扩展包类的 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
{
// in this method you can manipulate the service container:
// for example, changing some container service:
$container->getDefinition('app.some_private_service')->setPublic(true);
// or processing tagged services:
foreach ($container->findTaggedServiceIds('some_tag') as $id => $tags) {
// ...
}
}
}
或者,当使用单独的编译器 pass 类时,扩展包可以在其主扩展包类的 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 中引入“transport”标签,你可以将其命名为 acme_mailer.transport
。
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可获得许可。