【问题标题】:Impossible to pass the router service to a twig extension in symfony 2.6在 symfony 2.6 中无法将路由器服务传递给树枝扩展
【发布时间】:2015-04-24 22:33:38
【问题描述】:

我有一个树枝扩展,我试图在其中注入路由器服务,所以... 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; }

所以我删除了类型提示并转储对象以查看构造方法中的内容。令我惊讶的是,这是输出:

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());

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

【问题讨论】:

  • 只是为了笑,拿出 public: false 属性。您可以忽略这一点,因为文档显示使用 public: false。
  • 完成!问题显然仍然存在:)
  • 取出骰子();可能在没有路由器的情况下第二次调用构造。
  • 好吧。您正在进行某种奇怪的配置操作。我要做的是关闭一个新的 Symfony 项目,然后添加你的 twig 扩展并确保它正确加载。然后试着弄清楚有什么区别。似乎您在某处有编译器通过?或者也许两个服务都引用你的类?我假设您在重建时完全删除了缓存目录。
  • 我发现了问题...我有两个配置不同的 services.yml 文件,它们导致了问题。谢谢大家的时间:)

标签: php symfony dependency-injection router


【解决方案1】:

Twig 环境可用于\Twig_SimpleFunction 实例以及\Twig_SimpleFilter 以同样的方式,尽管Twig 文档only show it for filters。从环境中,你可以得到这样的路由扩展:

/**
 * {@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)); 然后倾倒调用任何你喜欢的东西的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    相关资源
    最近更新 更多