Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/232.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 使用EventListener简化Symfony中@Route调用的过程_Php_Symfony_Event Listener - Fatal编程技术网

Php 使用EventListener简化Symfony中@Route调用的过程

Php 使用EventListener简化Symfony中@Route调用的过程,php,symfony,event-listener,Php,Symfony,Event Listener,我在Symfony的每一条路线上都需要一个“标准程序”。 我基本上创建了一个简短的(相对)唯一的编号,检查权限并记录调用该函数的情况 以下是一个例子: ** * @Route("/_ajax/_saveNewClient", name="saveNewClient") */ public function saveNewClientAction(Request $request) { /* Create Unique TrackNumber */ $unique= $thi

我在Symfony的每一条路线上都需要一个“标准程序”。 我基本上创建了一个简短的(相对)唯一的编号,检查权限并记录调用该函数的情况

以下是一个例子:

**
 * @Route("/_ajax/_saveNewClient", name="saveNewClient")
 */
public function saveNewClientAction(Request $request)
{

    /* Create Unique TrackNumber */
    $unique= $this->get('log')->createUnique();

    /* Check Permission */
    if (!$permission = $this->get('permission')->needsLevel(2, $unique)) {

        /* Log Action */
        $this->get('log')->writeLog('No Permission, 2 needed', __LINE__, 4);
        return new JsonResponse(array(
                'result' => 'error',
                'message' => 'Insufficient Permission'
            )
        );
    }

    /* Log Action */
    $this->get('log')->writeLog('called '.__FUNCTION__, __LINE__, 1, $unique);

    return $this->render(':admin:index.html.twig', array());

}
有没有办法把所有这些放在一个函数的某个地方

函数中的其他部分也会调用
writeLog
,因此我不想将其与permisson检查结合起来,尽管这当然是可能的

创建EventListener时,我是否仍然必须在每个函数中调用它,或者是否可以自动调用它


任何暗示都感谢

您可以尝试制作一个beforefilter

如何设置前后过滤器

在web应用程序开发中,经常需要在控制器作为过滤器或挂钩的操作之前或之后执行一些逻辑

有些web框架定义了preExecute()和postExecute()等方法,但Symfony中没有这样的方法。好消息是,有一种更好的方法可以使用EventDispatcher组件干扰请求->响应过程

令牌验证示例

假设您需要开发一个API,其中一些控制器是公共的,而另一些控制器仅限于一个或多个客户端。对于这些私有特性,您可以向您的客户机提供一个令牌来标识自己

因此,在执行控制器操作之前,您需要检查该操作是否受到限制。如果受到限制,则需要验证提供的令牌

请注意,为了简单起见,此配方中的令牌将在配置中定义,不会使用数据库设置或通过安全组件进行身份验证

使用kernel.controller事件筛选之前

首先,使用config.yml和参数键存储一些基本令牌配置:

亚马尔

要检查的标签控制器

在控制器执行之前,kernel.controller侦听器会在每个请求上收到通知。因此,首先,您需要某种方法来确定与请求匹配的控制器是否需要令牌验证

一种干净简单的方法是创建一个空接口,并让控制器实现它:

namespace AppBundle\Controller;

interface TokenAuthenticatedController
{
    // ...
}
实现此接口的控制器如下所示:

namespace AppBundle\Controller;

use AppBundle\Controller\TokenAuthenticatedController;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FooController extends Controller implements TokenAuthenticatedController
{
    // An action that needs authentication
    public function barAction()
    {
        // ...
    }
}
创建事件侦听器

接下来,您需要创建一个事件侦听器,它将保存您希望在控制器之前执行的逻辑。如果您不熟悉事件监听器,可以在如何创建事件监听器和订阅服务器中了解有关事件监听器的更多信息:

// src/AppBundle/EventListener/TokenListener.php
namespace AppBundle\EventListener;

use AppBundle\Controller\TokenAuthenticatedController;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class TokenListener
{
    private $tokens;

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

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

        /*
         * $controller passed can be either a class or a Closure.
         * This is not usual in Symfony but it may happen.
         * If it is a class, it comes in array format
         */
        if (!is_array($controller)) {
            return;
        }

        if ($controller[0] instanceof TokenAuthenticatedController) {
            $token = $event->getRequest()->query->get('token');
            if (!in_array($token, $this->tokens)) {
                throw new AccessDeniedHttpException('This action needs a valid token!');
            }
        }
    }
}
注册侦听器

最后,将侦听器注册为服务,并将其标记为事件侦听器。通过监听kernel.controller,您告诉Symfony您希望在执行任何控制器之前调用您的侦听器

亚马尔


通过此配置,您的TokenListener onKernelController方法将在每个请求上执行。如果即将执行的控制器实现了TokenAuthenticatedController,则应用令牌身份验证。这使您可以在任何想要的控制器上使用“before”过滤器。

您可以尝试创建before过滤器

如何设置前后过滤器

在web应用程序开发中,经常需要在控制器作为过滤器或挂钩的操作之前或之后执行一些逻辑

有些web框架定义了preExecute()和postExecute()等方法,但Symfony中没有这样的方法。好消息是,有一种更好的方法可以使用EventDispatcher组件干扰请求->响应过程

令牌验证示例

假设您需要开发一个API,其中一些控制器是公共的,而另一些控制器仅限于一个或多个客户端。对于这些私有特性,您可以向您的客户机提供一个令牌来标识自己

因此,在执行控制器操作之前,您需要检查该操作是否受到限制。如果受到限制,则需要验证提供的令牌

请注意,为了简单起见,此配方中的令牌将在配置中定义,不会使用数据库设置或通过安全组件进行身份验证

使用kernel.controller事件筛选之前

首先,使用config.yml和参数键存储一些基本令牌配置:

亚马尔

要检查的标签控制器

在控制器执行之前,kernel.controller侦听器会在每个请求上收到通知。因此,首先,您需要某种方法来确定与请求匹配的控制器是否需要令牌验证

一种干净简单的方法是创建一个空接口,并让控制器实现它:

namespace AppBundle\Controller;

interface TokenAuthenticatedController
{
    // ...
}
实现此接口的控制器如下所示:

namespace AppBundle\Controller;

use AppBundle\Controller\TokenAuthenticatedController;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class FooController extends Controller implements TokenAuthenticatedController
{
    // An action that needs authentication
    public function barAction()
    {
        // ...
    }
}
创建事件侦听器

接下来,您需要创建一个事件侦听器,它将保存您希望在控制器之前执行的逻辑。如果您不熟悉事件监听器,可以在如何创建事件监听器和订阅服务器中了解有关事件监听器的更多信息:

// src/AppBundle/EventListener/TokenListener.php
namespace AppBundle\EventListener;

use AppBundle\Controller\TokenAuthenticatedController;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;

class TokenListener
{
    private $tokens;

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

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

        /*
         * $controller passed can be either a class or a Closure.
         * This is not usual in Symfony but it may happen.
         * If it is a class, it comes in array format
         */
        if (!is_array($controller)) {
            return;
        }

        if ($controller[0] instanceof TokenAuthenticatedController) {
            $token = $event->getRequest()->query->get('token');
            if (!in_array($token, $this->tokens)) {
                throw new AccessDeniedHttpException('This action needs a valid token!');
            }
        }
    }
}
注册侦听器

最后,将侦听器注册为服务,并将其标记为事件侦听器。通过监听kernel.controller,您告诉Symfony您希望在执行任何控制器之前调用您的侦听器

亚马尔

通过此配置,您的TokenListener onKernelController方法将在每个请求上执行。如果即将执行的控制器实现了TokenAuthenticatedController,则应用令牌身份验证。这让你有