在symfony 2.6中,无法将路由器服务传递给分支扩展


Impossible to pass the router service to a twig extension in symfony 2.6

我有一个分支扩展,我试图在其中注入路由器服务,所以。。。services.yml

app.twig_extension:
    class: SeoReportBundle'Twig'SeoReportExtension
    arguments: [@router]
    tags:
        - { name: twig.extension }

扩展:

使用Symfony''Bundle''FrameworkBundle''Routing''Router;

class SeoReportExtension extends 'Twig_Extension
{
    private $router;
    public function __construct(Router $router)
    {
        $this->router = $router;
    }

当我执行代码时,我得到了这个错误:

可捕获的致命错误:传递给SeoReportBundle''Twig''SeoReportExtension::__construct()的参数1必须是Symfony''Bundle''FrameworkBundle''Routing''Router的实例,未给定

为了调试它,我对代码进行了更改,试图了解发生了什么:

public function __construct($router) {
    var_dump($router);die();
    $this->router = $router; }

因此,我删除了类型提示,并对对象进行了转储,以查看construct方法中得到了什么。令我惊讶的是,这是输出:

Object(Symfony'Bundle'FrameworkBundle'Routing'Router)[198]
private 'container' => 
object(appDevDebugProjectContainer)[219]
private 'parameters' => ...

所以。。。它实际上传递了一个路由器对象。那么…为什么我会出错?我在这一点上完全输了

---更新---以下是我迄今为止的发现:-在/app/cache/dev/appDevDebugProjectContainer.php中,有两个地方可以创建扩展:

protected function getApp_TwigExtensionService()
    {
        return $this->services['app.twig_extension'] = new 'SeoReportBundle'Twig'SeoReportExtension($this->get('router'));
    }

哪个是正确的,它将路由器传递给构造和

protected function getTwigService()
{
    $this->services['twig'] = $instance = new 'Twig_Environment($this->get('twig.loader'), array('debug' => true, 'strict_variables' => true, 'exception_controller' => 'twig.controller.exception:showAction', 'form_themes' => array(0 => 'form_div_layout.html.twig'), 'autoescape' => array(0 => 'Symfony''Bundle''TwigBundle''TwigDefaultEscapingStrategy', 1 => 'guess'), 'cache' => (__DIR__.'/twig'), 'charset' => 'UTF-8', 'paths' => array()));
    $instance->addExtension($this->get('app.twig_extension'));
    ...
    $instance->addExtension(new 'Symfony'Bundle'AsseticBundle'Twig'AsseticExtension($this->get('assetic.asset_factory'), $this->get('templating.name_parser'), true, array(), array(0 => 'SeoReportBundle'), new 'Symfony'Bundle'AsseticBundle'DefaultValueSupplier($this)));
    $instance->addExtension(new 'Doctrine'Bundle'DoctrineBundle'Twig'DoctrineExtension());
    $instance->addExtension(new 'SeoReportBundle'Twig'SeoReportExtension());

现在,这个没有通过路由器。但它确实将一些依赖项传递给了其他扩展。因此,我的扩展不起作用是有原因的。

Twig环境以相同的方式可用于'Twig_SimpleFunction实例和'Twig_SimpleFilter,尽管Twig文档仅为筛选器显示它。从环境中,您可以获得如下路由扩展:

/**
 * {@inheritdoc}
 */
public function getFunctions(): array
{
    return array(
        new 'Twig_SimpleFunction('get_my_link_thing', array($this, 'getMyLinkThing'), array('needs_environment' => true)),
    );
}
/**
 * Get something with a generated link.
 *
 * @return string
 */
public function getMyLinkThing('Twig_Environment $env): string
{
    $targetUrl = $env->getExtension('routing')->getPath('my_route_name');
    return sprintf('Link is <a href="%s">here</a>!', $targetUrl);
}

$env中还有很多其他漂亮的东西——值得尝试dump(get_class_methods($env));,然后丢弃调用任何你喜欢的东西的结果。