跳到内容

如何使用编译器 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 许可获得许可。
目录
    版本