Php 什么';这是“什么?”;对",;从另一个bundle重写symfony扩展的方法

Php 什么';这是“什么?”;对",;从另一个bundle重写symfony扩展的方法,php,symfony,twig,Php,Symfony,Twig,我需要覆盖该文件 /供应商/symfony/symfony/src/symfony/Bundle/TwigBundle/Extension/assetextension.php 它使用twig函数“asset”从bundle加载twig getAssetUrl /** * Returns a list of functions to add to the existing list. * * @return array An array of functions */ public fu

我需要覆盖该文件 /供应商/symfony/symfony/src/symfony/Bundle/TwigBundle/Extension/assetextension.php

它使用twig函数“asset”从bundle加载twig getAssetUrl

/**
 * Returns a list of functions to add to the existing list.
 *
 * @return array An array of functions
 */
public function getFunctions()
{
    return array(
        new \Twig_SimpleFunction('asset', array($this, 'getAssetUrl')),
        new \Twig_SimpleFunction('assets_version', array($this, 'getAssetsVersion')),
    );
}

我希望在不接触核心文件的情况下重写asset()twig函数,否则下一次symfony更新将覆盖核心文件。请考虑您的代码位于AppBundle命名空间中。首先在app/config.yml或src/AppBundle/Resources/config/something.yml中创建服务配置(您必须在中加载此配置文件)。别忘了把它放在服务键下

twig.extension.assets:
    class:     AppBundle\Twig\AssetsExtension
    arguments: ["@service_container", "@?router.request_context"]
    public: false
    tags:
        - { name: twig.extension }
现在,让我们创建扩展src/AppBundle/Twig/assetextension.php。此类继承自原始扩展,我将只重写一个方法(在template asset()中)


我提供了另一个解决方案,因为自symfony 3.0以来,服务的类名不再可重写。
您必须选择编译器传递解决方案

假设您要覆盖twig中的url()函数,则应为其创建编译器过程并更改定义:

<?php
// AppBundle/AppBundle.php

namespace AppBundle;

use AppBundle\DependencyInjection\Compiler\TwigRoutingExtensionPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

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

        $container->addCompilerPass(new TwigRoutingExtensionPass());
    }
}

您也可以将参数twig.extension.assets.class设置为指向新的扩展类,而不是复制服务定义。但是编译器传递确实是最好的解决方案。实际上,我对更改getAssertUrl的必要性表示怀疑。可能会造成更多的麻烦,特别是如果你使用任何第三方模板。考虑只写自己的扩展和函数。是的,这是真的。还可以使用自定义扩展名设置参数twig.extension.assets.class。问题很清楚-如何在不接触Symfony代码的情况下重写asset()。我真的不知道为什么user3531149需要这个用例。你的解决方案很好。希望这不是另一个驾车路过。我尝试了您的解决方案,但我收到一个错误
“Symfony\Bridge\Twig\Extension\TranslationExtension”扩展未在
中启用。在我的情况下,我尝试重写trans()函数。有什么想法吗?对不起,你启用翻译了吗?
<?php
// AppBundle/AppBundle.php

namespace AppBundle;

use AppBundle\DependencyInjection\Compiler\TwigRoutingExtensionPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

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

        $container->addCompilerPass(new TwigRoutingExtensionPass());
    }
}
<?php
// AppBundle/DependencyInjectoin/Compiler/TwigRoutingExtensionPass.php    

namespace AppBundle\DependencyInjection\Compiler;

use AppBundle\Twig\Extension\RoutingExtension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;

class TwigRoutingExtensionPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if (false === $container->hasDefinition('twig.extension.routing')) {
            return;
        }

        $definition = $container->getDefinition('twig.extension.routing');
        $definition->setClass(RoutingExtension::class);
    }
}
<?php

    $definition->addArgument('some_service');
    // OR
    $definition->addMethodCall('setSomeService' [$container->get('some_service')]);