【问题标题】:Symfony dependency injection in twig extension树枝扩展中的 Symfony 依赖注入
【发布时间】:2014-07-23 17:03:03
【问题描述】:

好的,我试图创建依赖于其他服务的树枝扩展 (security.context) 并遇到了一些麻烦。所以,这是我的服务声明:

acme.twig.user_extension:
        class: Acme\BaseBundle\Twig\UserExtension
        arguments: ["@security.context"]
        tags:
            - { name: twig.extension }

这是我的课

// acme/basebundle/twig/userextension.php

namespace Acme\BaseBundle\Twig;

use Symfony\Component\Security\Core\SecurityContext;
use Acme\UserBundle\Entity\User;

class UserExtension extends \Twig_Extension
{

    protected $context;

    public function __construct(SecurityContext $context){
        $this->context = $context;
    }

    public function getFunctions()
    {
        return array(
            'getAbcData' => new \Twig_SimpleFunction('getAbcData', $this->getAbcData()),
        );
    }

    public function getAbcData()
    {
        if ( !is_object($user = $this->context->getToken()->getUser()) || !$user instanceof User){ return null; }
        return array(
            'data_array'   => $user->getData(),
        );
    }

    public function getName()
    {
        return 'user_extension';
    }
}

最后,我有一个错误:

FatalErrorException: Error: Call to a member function getUser() on a non-object in \src\Acme\BaseBundle\Twig\UserExtension.php line 27

我猜 security.context 服务还没有初始化,然后我得到一个错误。 请问有没有办法手动加载服务,或者有什么更好的解决方案? 非常感谢。


我使用 Symfony 2.5.*

更新:

我也在 symfony 文档中找到了这个通知

请记住,Twig 扩展不会延迟加载。这意味着如果任何服务(或在这种情况下是您的 Twig 扩展)依赖于请求服务,您将更有可能获得 CircularReferenceException 或 ScopeWideningInjectionException。有关更多信息,请查看如何使用范围。 实际上,我不知道如何正确地做到这一点..

【问题讨论】:

    标签: symfony service dependency-injection twig


    【解决方案1】:

    您在构造 Twig_SimpleFilter 时调用 $this->getAbcData()。但是你必须传递一个callable 作为参数。

    public function getFunctions() {
        return array (
            'getAbcData' => new \Twig_SimpleFunction( 'getAbcData', array( $this, 'getAbcData' ))
        );
    }
    

    Leo 也是对的。在尝试getToken()->getUser() 之前,您应该先检查getToken() 是否正在返回一个对象。

    您还可以将用户作为 twig 中的参数传递给函数:{{ getAbcData(app.user) }}。这样该函数就更通用了,可以用于任何用户,而不仅仅是当前登录的用户。

    【讨论】:

    • 就像 Qwertz 说的那样,您可以传输您的用户以获得通用性。如果你的树枝扩展只是从你的用户对象中获取一个方法,你可以做 app.user.getData() 或 app.user.data。
    【解决方案2】:

    这应该可行。该错误消息意味着 getToken() 不是对象,因此您必须先测试 getToken() 是否是对象,然后再测试 getUser() 是否也是对象。

    public function getAbcData()
    {
        $token = $this->context->getToken();
    
        if (!is_object($token) || !is_object($token->getUser())) {
            return null;
        }
    
        return array(
            'data_array'   => $user->getData(),
        );
    }
    

    【讨论】:

    • 谢谢你,里奥。但问题是我实际上有令牌,因为我已经过身份验证。请查看我的问题的 UPD。
    【解决方案3】:

    您需要更改 twig 扩展以将容器而不是安全上下文传递给构造函数。

    Twig_Extensions 的特殊之处在于,不传入容器而是只传入你需要的内容的常规规则通常不适用,因为它会由于范围问题而导致问题。

    所以把你的扩展改成这样。

    // acme/basebundle/twig/userextension.php
    
    namespace Acme\BaseBundle\Twig;
    
    use Symfony\Component\DependencyInjection\ContainerInterface;
    use Symfony\Component\Security\Core\SecurityContext;
    use Acme\UserBundle\Entity\User;
    
    class UserExtension extends \Twig_Extension
    {
        /**
         * @var \Symfony\Component\DependencyInjection\ContainerInterface
         */
        protected $container;
    
        public function __construct(ContainerInterface $container){
            $this->container = $container;
        }
    
        public function getFunctions()
        {
            return array(
                'getAbcData' => new \Twig_SimpleFunction('getAbcData', $this->getAbcData()),
            );
        }
    
        public function getAbcData()
        {
            if ( !is_object($user = $this->container->get('security.context')->getToken()->getUser()) || !$user instanceof User){ return null; }
            return array(
                'data_array'   => $user->getData(),
            );
        }
    
        public function getName()
        {
            return 'user_extension';
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-22
      • 1970-01-01
      • 2014-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多