Symfony 包继承 - 如何覆盖/扩展服务类

And*_*ord 2 php inheritance symfony

在我的Symfony 2.8项目中,我使用包继承来覆盖/扩展FOSUserBundle:自定义包中具有相同路径和名称的文件会覆盖FOSUserBundle.

虽然这对于控制器和资源(如翻译和视图)工作得很好,但它似乎不适用于服务类。

例如,FOSUserBundle用于Resources\config\util.xml定义fos_user.util.password_updater服务以使用 中定义的类Util\PasswordUpdater.php

简单地将 a 添加Util\PasswordUpdater.php到继承的包中是行不通的。该文件将被忽略,并且捆绑包仍使用原始版本。

这是服务的缩进行为(因为原始服务定义仍然指向原始文件),还是我做错了什么?

覆盖/扩展服务的正确方法是什么?我发现信息表明使用 acompiler pass通常是最好的解决方案。但是,当已经使用包继承时,这也是正确的/有意的吗?

Raw*_*ner 5

要覆盖服务,您需要在 Bundle 中创建 CompilerPass:

<?php

namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Class OverrideServiceCompilerPass
 * @package Shopmacher\IsaBodyWearBundle\DependencyInjection\Compiler
 */
class OverrideServiceCompilerPass implements CompilerPassInterface
{

    /**
     * Overwrite project specific services
     * @param ContainerBuilder $container
     */
    public function process(ContainerBuilder $container)
    {
        $defNewService = $container->getDefinition('service.id.you.want.to.override');
        $defNewService ->setClass('AppBundle\Service\NewService');

    }
}
Run Code Online (Sandbox Code Playgroud)

将其注册到您的 Bundle 文件中:

class AppBundle extends FOSUserBundle
{
    public function build(ContainerBuilder $container)
    {
        parent::build($container);

        $container->addCompilerPass(new OverrideServiceCompilerPass());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后您的服务文件将被加载。在此文件中,您可以扩展原始服务文件并共享方法,也可以创建全新的服务。