如何防止Symfony探查器访问或执行侦听器 [英] How to prevent Symfony profiler from accessing or executing a listener

查看:115
本文介绍了如何防止Symfony探查器访问或执行侦听器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的用户具有 countTasks 个属性,并带有相应的setter和getter:

My user has countTasks property, with corresponding setter and getter:

class User implements UserInterface, \Serializable
{
    /**
     * @var integer
     */
    private $countTasks;
}

我希望此属性始终显示在应用程序的导航栏中( 14红色数字):

I want this property to be always shown in the application's navigation bar (the "14" number in red):

显然,应该为每个控制器设置此属性。 (实际上,仅针对处理渲染导航栏的每个对象,但实际情况并非如此)。因此,应用程序应为每个控制器计算当前登录用户的任务。

Obviously, this property should be set for every controller. (Actually, only for every that deals with rendering the navigation bar, but that's not the case here). So the application should count tasks for the currently logged-in user for every controller.

我在Symfony食谱中找到了一个相关主题:如何在过滤器之前和之后进行设置,我设法实现了这一点:

I found a relevant topic in the Symfony cookbook: How to Setup before and after Filters, and I managed to implement it:

Acme\TestBundle\EventListener\UserListener.php

namespace Acme\TestBundle\EventListener;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class UserListener
{
    public function onKernelController(FilterControllerEvent $event)
    {
        $controller = $event->getController();

        if ( ! is_array($controller)) {
            return;
        }

        $securityContext = $controller[0]->get('security.context');

        // now count tasks, but only if a user logged-in
        if ($securityContext->isGranted('IS_AUTHENTICATED_REMEMBERED') or $securityContext->isGranted('IS_AUTHENTICATED_FULLY'))
        {
            $user = $securityContext->getToken()->getUser();

            // ...
            // countig tasks and setting $countTasks var
            // ...
            $user->setCountTasks($countTasks);
        }
    }
}

services.yml

services:
    acme.user.before_controller:
        class: Acme\TestBundle\EventListener\UserListener
        tags:
            - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }

它可以按预期工作,并且我可以像下面这样在Twig模板中提取属性:

It works as expected and I'm able to pull the property in a Twig template like this:

{{ app.user.countTasks }}

它在产品环境中按预期工作。

但是在开发人员中,探查器会抛出 UndefinedMethodException

It works as expected in prod env.
In dev however, profiler throws UndefinedMethodException:


UndefinedMethodException:尝试在... \src\Acme\TestBundle\中的类 Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController上调用方法 get \EventListener\UserListener.php第18行。

UndefinedMethodException: Attempted to call method "get" on class "Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController" in ...\src\Acme\TestBundle\EventListener\UserListener.php line 18.

其中第18行是

$securityContext = $controller[0]->get('security.context');

作为一个快速补丁,我添加了额外的检查(在第18行之前)以防止探查器执行其他逻辑:

As a quick patch I added additional check (before line 18) to prevent profiler from executing the further logic:

    if (is_a($controller[0], '\Symfony\Bundle\WebProfilerBundle\Controller\ProfilerController'))
    {
        return;
    }

    $securityContext = $controller[0]->get('security.context');

,它就成功了。但是,恐怕这不是正确的方法。我也担心会丢失分析器中的某些调试信息。

and it has made the trick. But I'm afraid it's not the right way. I'm also afraid that I'm loosing some part of debug information in profiler.

我对我的担忧满意吗?您能指出我一种阻止Profiler执行此侦听器的更好方法吗?

Am I right with my concerns? Can you point me to a better way to prevent profiler from executing this listener? In config somehow?

推荐答案

一开始,我试图以相反的方式解决此问题。在测试期间,事实证明我也必须排除其他一些核心控制器。当然,我应该只允许必需的控制器,而不是阻止不需要的控制器。

In the beginning I was trying to fix the issue conversely than I should. During testing it turned out that I have to exclude some other core controllers too. Of course, rather than block unwanted controllers I should have allowed the required ones only.

我最终创建了一个空接口 UserTasksAwareController

I ended up creating an empty interface UserTasksAwareController:

namespace Acme\TestBundle\Controller;

interface UserTasksAwareController
{}

修复该有效性检查 UserListener.php

if ( ! $controllers[0] instanceof UserTasksAwareController) {
    return;
}

并在处理显示 countTasks 属性,如下所示:

and implementing it in every other controller which deals with displaying countTasks property, like this one:

class UserController extends Controller implements UserTasksAwareController

所以,当您忘记编写接口程序而不是实现程序时,我遇到的问题只是另一个。

So, the problem I had was just another one when you forget to program to an interface, not an implementation.

这篇关于如何防止Symfony探查器访问或执行侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆