【问题标题】:How to access route parameters from a service tagged monolog.processor?如何从标记为 monolog.processor 的服务访问路由参数?
【发布时间】:2021-11-08 06:53:08
【问题描述】:

使用 Symfony 4.4,如果在请求中找到它,我想动态添加到我所有的路由参数中。例如。对于用户 ID:

PUT | DELETE | POST mywebsite.com/users/{userid}/some-action

我可以在每次登录时添加我的用户 ID,但这有点麻烦。

所以我创建了一个服务:

//src/
// |__Services/
//         |___UserProcessor.php

use Monolog\Processor\ProcessorInterface;
use Symfony\Component\HttpFoundation\RequestStack;

// In my config.yaml this monolog.processor
final class UserProcessor implements ProcessorInterface
{
    private RequestStack $requestStack;
    public function __construct(RequestStack $requestStack)
    {
        $this->requestStack = $requestStack;
    }

    public function __invoke(array $record): array
    {
        dd($this->requestStack->getMasterRequest()->attributes);
    }
}

当我在 POST /users/{userid}/some-action 上运行我的邮递员时,我得到以下输出:

[
      "media_type" => "application/json"
]

据我了解,在我的处理器运行时,symfony 路由参数request attributes 尚未构建。

我应该怎么做才能让我的处理器访问属性userid

【问题讨论】:

    标签: php symfony monolog


    【解决方案1】:

    检查Symfony\Bridge\Monolog\Processor\RouteProcessor 是如何做到的:

    它被实现为EventSubscriber

    class RouteProcessor implements EventSubscriberInterface, ResetInterface
    {
        private $routeData;
        private $includeParams;
    
        public function __construct(bool $includeParams = true)
        {
            $this->includeParams = $includeParams;
            $this->reset();
        }
    
        public static function getSubscribedEvents(): array
        {
            return [
                KernelEvents::REQUEST => ['addRouteData', 1],
                KernelEvents::FINISH_REQUEST => ['removeRouteData', 1],
            ];
        }
    // rest of the implementation
    }
    
    

    KernelEvents::REQUEST 期间,它将所需的请求数据(包括请求参数,如果需要)添加到对象的内部状态,因此当处理器运行时,它可以从内部RouteProcessor::$routeData 访问数据,而不是直接来自请求。

     public function addRouteData(RequestEvent $event)
        {
            if ($event->isMainRequest()) {
                $this->reset();
            }
    
            $request = $event->getRequest();
            if (!$request->attributes->has('_controller')) {
                return;
            }
    
            $currentRequestData = [
                'controller' => $request->attributes->get('_controller'),
                'route' => $request->attributes->get('_route'),
            ];
    
            if ($this->includeParams) {
                $currentRequestData['route_params'] = $request->attributes->get('_route_params');
            }
    
            $this->routeData[spl_object_id($request)] = $currentRequestData;
        }
    

    您可以修改此方法以适合自己,甚至直接使用此处理器(尽管它添加的数据比您在问题中寻找的数据更多)。

    【讨论】:

      猜你喜欢
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-24
      • 2017-01-15
      • 2016-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多