mirror of
https://github.com/symfony/symfony-docs.git
synced 2026-03-24 00:32:14 +01:00
127 lines
4.4 KiB
ReStructuredText
127 lines
4.4 KiB
ReStructuredText
How to Work with Compiler Passes
|
|
================================
|
|
|
|
Compiler passes give you an opportunity to manipulate other
|
|
:doc:`service definitions </service_container/definitions>` that have been
|
|
registered with the service container.
|
|
|
|
.. _kernel-as-compiler-pass:
|
|
|
|
If your compiler pass is relatively small, you can define it inside the
|
|
application's ``Kernel`` class instead of creating a
|
|
:ref:`separate compiler pass class <components-di-separate-compiler-passes>`.
|
|
|
|
To do so, make your kernel implement :class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface`
|
|
and add the compiler pass code inside the ``process()`` method::
|
|
|
|
// 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) {
|
|
// ...
|
|
}
|
|
}
|
|
}
|
|
|
|
If you create separate compiler pass classes, enable them in the ``build()``
|
|
method of the application kernel::
|
|
|
|
// 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());
|
|
}
|
|
}
|
|
|
|
Working with Compiler Passes in Bundles
|
|
---------------------------------------
|
|
|
|
:doc:`Bundles </bundles>` can define compiler passes in the ``build()`` method of
|
|
the main bundle class (this is not needed when implementing the ``process()``
|
|
method in the extension)::
|
|
|
|
// 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
|
|
{
|
|
$container->addCompilerPass(new CustomPass());
|
|
}
|
|
}
|
|
|
|
If your compiler pass is relatively small, you can make the main bundle class implements
|
|
:class:`Symfony\\Component\\DependencyInjection\\Compiler\\CompilerPassInterface` so that
|
|
it can add itself::
|
|
|
|
// src/MyBundle/MyBundle.php
|
|
namespace App\MyBundle;
|
|
|
|
use App\DependencyInjection\Compiler\CustomPass;
|
|
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
use Symfony\Component\HttpKernel\Bundle\AbstractBundle;
|
|
|
|
class MyBundle extends AbstractBundle implements CompilerPassInterface
|
|
{
|
|
|
|
public function build(ContainerBuilder $container): void
|
|
{
|
|
$container->addCompilerPass($this);
|
|
}
|
|
|
|
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) {
|
|
// ...
|
|
}
|
|
}
|
|
}
|
|
|
|
If you are using custom :doc:`service tags </service_container/tags>` in a
|
|
bundle, the convention is to format tag names by starting with the bundle's name
|
|
in lowercase (using underscores as separators), followed by a dot, and finally
|
|
the specific tag name. For example, to introduce a "transport" tag in your
|
|
AcmeMailerBundle, you would name it ``acme_mailer.transport``.
|