【问题标题】:Can I get current route information in middleware with Lumen?我可以使用 Lumen 在中间件中获取当前路由信息吗?
【发布时间】:2015-08-15 04:12:28
【问题描述】:

我需要将当前找到的控制器和操作放在中间件中,以便进行一些身份验证。但我发现这是不可能的,因为管道就像 Middleware1 -> Middleware2-> do the dispatching -> controller@action() -> Middleware2 -> Middleware1。

因此,在派送之前,我无法获得路线信息。在 $controller->action() 之后这样做肯定是不对的。

我做了一些研究,发现了这个。

$allRoutes = $this->app->getRoutes();
$method = \Request::getMethod();
$pathInfo = \Request::getPathInfo();
$currentRoute = $allRoutes[$method.$pathInfo]['action']['uses'];

但这在访问像app/role/1 这样的URI 时不起作用,因为$allRoutes 只有app/role/{id} 的索引而不是app/role/1

有什么解决方法吗?

【问题讨论】:

  • 您需要什么信息?
  • @peterm 我需要在调用动作之前在中间件中获取匹配的路由信息​​,包括控制器名称、动作名称。
  • 我已将请求拉到 Lumen 5.0 并等待合并。

标签: php laravel lumen


【解决方案1】:

经过一番研究,我得到了解决方案。他们来了:

创建自定义调度程序

首先,您必须制作自己的自定义调度程序,我的是:

App\Dispatcher\GroupCountBased

存储为:

app/Dispatcher/GroupCountBased.php

这是GroupCountBased的内容:

<?php namespace App\Dispatcher;

use FastRoute\Dispatcher\GroupCountBased as BaseGroupCountBased;

class GroupCountBased extends BaseGroupCountBased
{
    public $current;

    protected function dispatchVariableRoute($routeData, $uri) {
        foreach ($routeData as $data) {
            if (!preg_match($data['regex'], $uri, $matches)) continue;

            list($handler, $varNames) = $data['routeMap'][count($matches)];

            $vars = [];
            $i = 0;

            foreach ($varNames as $varName) {
                $vars[$varName] = $matches[++$i];
            }

            // HERE WE SET OUR CURRENT ROUTE INFORMATION
            $this->current = [
                'handler' => $handler,
                'args' => $vars,
            ];

            return [self::FOUND, $handler, $vars];
        }

        return [self::NOT_FOUND];
    }
}

在 Laravel 容器中注册您的自定义调度程序

然后,通过singleton() 方法注册您自己的自定义调度程序您注册所有路线后执行此操作!就我而言,我在bootstrap/app.php 中添加了自定义调度程序,在此行之后:

require __DIR__.'/../app/Http/routes.php';

这就是它的样子:

/*
|--------------------------------------------------------------------------
| Load The Application Routes
|--------------------------------------------------------------------------
|
| Next we will include the routes file so that they can all be added to
| the application. This will provide all of the URLs the application
| can respond to, as well as the controllers that may handle them.
|
*/

require __DIR__.'/../app/Http/routes.php';

// REGISTER YOUR CUSTOM DISPATCHER IN LARAVEL CONTAINER VIA SINGLETON METHOD
$app->singleton('dispatcher', function () use ($app) {
    return FastRoute\simpleDispatcher(function ($r) use ($app) {
        foreach ($app->getRoutes() as $route) {
            $r->addRoute($route['method'], $route['uri'], $route['action']);
        }
    }, [
        'dispatcher' => 'App\\Dispatcher\\GroupCountBased',
    ]);
});

// SET YOUR CUSTOM DISPATCHER IN APPLICATION CONTEXT
$app->setDispatcher($app['dispatcher']);

调用中间件(更新)

注意:我知道这并不优雅,因为dispatch 在中间件执行后调用,您必须手动调度调度程序。

在您的中间件中,在您的 handle 方法中,执行以下操作:

app('dispatcher')->dispatch($request->getMethod(), $request->getPathInfo());

例子:

public function handle($request, Closure $next)
{
    app('dispatcher')->dispatch($request->getMethod(), $request->getPathInfo());
    dd(app('dispatcher')->current);
    return $next($request);
}

用法

获取当前路线:

app('dispatcher')->current;

【讨论】:

  • 这个我没试过,但看起来很棒。我认为它应该工作。我会尽快更新。
  • 对不起,它不起作用。请检查此src code。在调度之前调用中间件。所以 Dispatcher 中的$current 始终为空,除非调用顺序发生变化。
  • 这确实获得了当前路线。但是,在您的解决方案中,调度发生了两次,请参阅here。还是谢谢。
  • 正如我所说,这不是优雅的方式,因为 dispatch 会调用两次。为避免这种情况,您可以更改应用程序中的调度方法。检查 dispatcher 是否已经派发,如果没有派发,反之亦然。
  • 我撤回了关于这个的请求。 here
【解决方案2】:

我找到了这个问题的正确答案。我错过了Application 中的一种名为routeMiddleware() 的方法。该方法注册了在调度后调用的特定于路由的中间件。所以只需使用$app-&gt;routeMiddleware() 注册你的中间件。并在您的中间件中通过$request-&gt;route() 获取匹配的路由信息​​。

【讨论】:

  • 请您解释一下,因为我不明白如何获取当前路线
【解决方案3】:
$methodName = $request->getMethod();
$pathInfo = $request->getPathInfo();
$route = app()->router->getRoutes()[$methodName . $pathInfo]['action']['uses'];
$classNameAndAction = class_basename($route);
$className = explode('@', $classNameAndAction)[0];

【讨论】:

  • 在 URL 中传递动态参数时,此解决方案失败。例如。 GET/api/visited-profiles/{recordsPerPage}/{pageIndex}。有什么建议吗?
猜你喜欢
  • 2015-12-25
  • 2011-02-27
  • 2018-02-10
  • 2016-12-16
  • 2016-04-01
  • 2016-06-08
  • 2018-06-30
  • 1970-01-01
  • 2021-06-21
相关资源
最近更新 更多