如何使用編譯器 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 授權條款授權。