【问题标题】:Twig GlobalsInterface breaks Symfony Debug ToolbarTwig GlobalsInterface 中断 Symfony 调试工具栏
【发布时间】:2019-06-14 05:41:42
【问题描述】:

Symfony 4.3.1

我有一个 Twig-Extension,我在其中将变量全局添加到 Twig。一旦我在课堂上实现Twig\Extension\GlobalsInterface,Symfony 调试工具栏就会呈现“加载 Web 调试工具栏时发生错误”。不过,这些变量可以完美地添加到全局范围中。

这是我的扩展:

<?php

namespace App\Twig;

use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Doctrine\ORM\EntityManagerInterface;
use Twig\Extension\AbstractExtension;
use Twig\Extension\GlobalsInterface;

class GlobalVarsExtension extends AbstractExtension implements GlobalsInterface
{
    protected $em;

    protected $tokenStorage;

    protected $authorizationChecker;

    public function __construct(EntityManagerInterface $em, AuthorizationCheckerInterface $authorizationChecker, TokenStorageInterface $tokenStorage)
    {
        $this->em = $em;
        $this->tokenStorage = $tokenStorage;
        $this->authorizationChecker = $authorizationChecker;
    }


    public function getGlobals()
    {
        $globalVars = [];

        if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
            if (null !== $token = $this->tokenStorage->getToken()) {
                $globalVars['user'] = $token->getUser();
            }
        }

        return $globalVars;
    }
}

这是我实现的接口:

<?php

/*
 * This file is part of Twig.
 *
 * (c) Fabien Potencier
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Twig\Extension;

/**
 * Enables usage of the deprecated Twig\Extension\AbstractExtension::getGlobals() method.
 *
 * Explicitly implement this interface if you really need to implement the
 * deprecated getGlobals() method in your extensions.
 *
 * @author Fabien Potencier <fabien@symfony.com>
 */
interface GlobalsInterface
{
    /**
     * Returns a list of global variables to add to the existing list.
     *
     * @return array An array of global variables
     */
    public function getGlobals();
}

class_alias('Twig\Extension\GlobalsInterface', 'Twig_Extension_GlobalsInterface');

我按照他们的文档添加全局变量:https://twig.symfony.com/doc/2.x/advanced.html#id1

这是来自 Twig 的更改日志,其中将方法声明为已弃用: https://twig.symfony.com/doc/1.x/deprecated.html#extensions

我错过了什么?还是有不同的方法添加全局变量?

编辑:

在意识到我完全错过了 symfony 错误日志并且错误出现的原因完全不同之后......

错误日志:

[2019-06-13 15:49:18] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException: "The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL." at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php line 49 {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49)"} []
[2019-06-13 15:49:18] request.CRITICAL: Exception thrown when handling an exception (Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException: The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php line 49) {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49)"} []
[2019-06-13 15:49:18] php.CRITICAL: Uncaught Exception: The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49, Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49)"} []
[2019-06-13 15:49:18] request.CRITICAL: Uncaught PHP Exception Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException: "The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL." at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php line 49 {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49, Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49)"} []
[2019-06-13 15:49:18] request.CRITICAL: Exception thrown when handling an exception (Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException: The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php line 49) {"exception":"[object] (Symfony\\Component\\Security\\Core\\Exception\\AuthenticationCredentialsNotFoundException(code: 0): The token storage contains no authentication token. One possible reason may be that there is no firewall configured for this URL. at /var/www/rekkt.de/vendor/symfony/security-core/Authorization/AuthorizationChecker.php:49)"} []

编辑2:

因此,对于给定的错误日志,这就是我所做的更改,现在运行良好。

public function getGlobals()
    {
        $globalVars = [];

        if (null !== $token = $this->tokenStorage->getToken()) {
            $globalVars['user'] = $token->getUser();
        }

        return $globalVars;
    }

【问题讨论】:

    标签: php symfony twig


    【解决方案1】:

    首先,您不应该在扩展程序中注入整个容器。

    始终尝试只注入您需要的东西。在您的示例中,您可以直接注入 AuthorizationCheckerInterface 而不是 ContainerInterface

    关于你的错误,如果没有日志,猜测起来有点棘手,但你应该在调用getUser() 之前尝试检查getToken() 方法是否没有返回null

    <?php
    
    namespace App\Twig;
    
    use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
    use Doctrine\ORM\EntityManagerInterface;
    use Twig\Extension\AbstractExtension;
    use Twig\Extension\GlobalsInterface;
    use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
    
    
    class GlobalVarsExtension extends AbstractExtension implements GlobalsInterface
    {
        protected $em;
    
        protected $tokenStorage;
    
        protected $authorizationChecker;
    
        public function __construct(EntityManagerInterface $em, AuthorizationCheckerInterface $authorizationChecker, TokenStorageInterface $tokenStorage)
        {
            $this->em = $em;
            $this->tokenStorage = $tokenStorage;
            $this->authorizationChecker = $authorizationChecker;
        }
    
    
       public function getGlobals()
       {
        $globalVars = [];
    
        if ($this->authorizationChecker->isGranted('IS_AUTHENTICATED_FULLY')) {
            if (null !== $token = $this->tokenStorage->getToken()) {
                $globalVars['user'] = $token->getUser();
            }
        }
    
        return $globalVars;
       }
    }
    

    【讨论】:

    • 两天前刚开始使用 symfony,完全忘记了单独的 symfony 日志文件,只是检查了 apache-erroglog,想知道为什么里面没有任何相关内容。我正在用您改进的代码和相关的错误日志更新我的问题。
    猜你喜欢
    • 2014-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多