Php 我可以在带有Lumen的中间件中获取当前路由信息吗?

Php 我可以在带有Lumen的中间件中获取当前路由信息吗?,php,laravel,lumen,Php,Laravel,Lumen,我需要在中间件中找到当前的控制器和操作,以便进行一些身份验证。但我发现这是不可能的,因为管道就像是Middleware1->Middleware2->执行调度->controller@action()->米德尔瓦2->米德尔瓦1 因此,在调度之前,我无法获取路线信息。在$controller->action()之后执行此操作肯定是不对的 我做了一些研究,发现了这个 $allRoutes = $this->app->getRoutes(); $method = \Request::ge

我需要在中间件中找到当前的控制器和操作,以便进行一些身份验证。但我发现这是不可能的,因为管道就像是Middleware1->Middleware2->执行调度->controller@action()->米德尔瓦2->米德尔瓦1

因此,在调度之前,我无法获取路线信息。在$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


有什么解决办法吗?

在做了一些研究之后,我找到了解决办法。他们来了:

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

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];
    }
}
这就是它看起来的样子:

/*
|--------------------------------------------------------------------------
| 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']);
调用中间件(更新) 注意:我知道这并不优雅,因为执行中间件后调用了
调度
,您必须手动调度调度程序

在中间件中的
句柄
方法中,执行以下操作:

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;

我找到了这个问题的正确答案。我错过了
应用程序
的一个名为
routeMiddleware()
的方法。此方法注册特定于路由的中间件,该中间件在分派后被调用。因此,只需使用
$app->routeMiddleware()
注册中间件即可。并通过中间件中的
$request->route()
获取匹配的路由信息。

您需要什么信息?@peterm在调用操作之前,我需要在中间件中获取匹配的路由信息,包括控制器名称、操作名称。我已将请求拉至Lumen 5.0并等待合并。我没有尝试过此操作,但它看起来很棒。我认为应该行得通。我很快就会更新。很抱歉,它不起作用。请检查这个。在分派之前调用中间件。因此,Dispatcher中的
$current
始终为空,除非调用顺序已更改。这将获取当前路由。然而,在您的解决方案中,调度发生了两次,请参阅。不管怎样,谢谢。正如我所说的,这不是一种优雅的方式,因为调度会打两次电话。为了避免这种情况,您可以在应用程序中更改分派方法。检查调度程序是否已被调度,如果未被调度,则执行调度,反之亦然。我拉取了关于此的请求。你能再解释一下吗?因为我不知道怎么走现在的路线
$methodName = $request->getMethod();
$pathInfo = $request->getPathInfo();
$route = app()->router->getRoutes()[$methodName . $pathInfo]['action']['uses'];
$classNameAndAction = class_basename($route);
$className = explode('@', $classNameAndAction)[0];
$methodName = $request->getMethod();
$pathInfo = $request->getPathInfo();
$route = app()->router->getRoutes()[$methodName . $pathInfo]['action']['uses'];
$classNameAndAction = class_basename($route);
$className = explode('@', $classNameAndAction)[0];