跳到內容

如何使用編譯器 Pass

編輯此頁面

編譯器 pass 讓您有機會操作已在服務容器中註冊的其他服務定義

如果您的編譯器 pass 相對較小,您可以將其定義在應用程式的 Kernel 類別中,而不是建立一個獨立的編譯器 pass 類別

若要這樣做,請讓您的 kernel 實作 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 類別,請在應用程式 kernel 的 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());
    }
}

在 Bundle 中使用編譯器 Pass

如果您的編譯器 pass 相對較小,您可以直接將其新增到主要的 bundle 類別中。若要這樣做,請讓您的 bundle 實作 CompilerPassInterface,並將編譯器 pass 程式碼放置在主要 bundle 類別的 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 類別時,bundle 可以在其主要 bundle 類別的 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());
    }
}

如果您在 bundle 中使用自訂服務標籤,慣例是以 bundle 名稱的小寫形式(使用底線作為分隔符號)開頭來格式化標籤名稱,後跟一個點,最後是特定的標籤名稱。例如,若要在您的 AcmeMailerBundle 中引入 "transport" 標籤,您會將其命名為 acme_mailer.transport

這項工作,包括程式碼範例,已根據 Creative Commons BY-SA 3.0 授權條款授權。
目錄
    版本