路由调度之运行路由
简介
运行路由主要做的工作:
- 1、设置请求对象 Request 的路由分解器属性
routeResolver
- 2、触发
Illuminate\Routing\Events\RouteMatched
事件,运行此事件关联的监听,即运行监听类中的 handle 方法 - 3、检测 Laravel 服务容器中有没有绑定
middleware.disable
,如果绑定了middleware.disable
,检测绑定的值是不是 true - 4、如果绑定了
middleware.disable
,且绑定的值是 true,则跳过路由中间件的过滤 - 5、如果没有绑定
middleware.disable
,或者绑定的值是 false,执行路由中间件获取任务
设置路由分解器
protected function runRoute(Request $request, Route $route)
{
// 调用 Request 对象的 setRouteResolver 方法,设置路由分解器
$request->setRouteResolver(function () use ($route) {
return $route;
});
$this->events->dispatch(new Events\RouteMatched($route, $request));
return $this->prepareResponse($request,
$this->runRouteWithinStack($route, $request)
);
}
public function setRouteResolver(Closure $callback)
{
// 将返回路由对象的闭包函数赋值给 routeResolver 属性
$this->routeResolver = $callback;
return $this;
}
触发 RouteMatched
事件
protected function runRoute(Request $request, Route $route)
{
$request->setRouteResolver(function () use ($route) {
return $route;
});
// 触发 `RouteMatched` 事件
$this->events->dispatch(new Events\RouteMatched($route, $request));
return $this->prepareResponse($request,
$this->runRouteWithinStack($route, $request)
);
}
关于 RouteMatched
事件监听的定义
1、设置
RouteMatched
事件的监听类App\Providers\EventServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Event;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Routing\Events\RouteMatched' => [
'App\Listeners\RouteMatchedListener',
],
];
/**
* Register any events for your application.
*
* @return void
*/
public function boot()
{
parent::boot();
//
}
}2、创建监听
php artisan make:listener RouteMatchedListener
3、编写监听类
App\Listeners\RouteMatchedListener
<?php
namespace App\Listeners;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Routing\Events\RouteMatched;
class RouteMatchedListener
{
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* @param RouteMatched $event
* @return void
*/
public function handle(RouteMatched $event)
{
// 获取请求对象
$event->request;
// 获取匹配好的路由对象
$event->route;
// 如果想在路由中间件过滤前,对请求对象或路由对象进行相关操作,可在此进行相应操作
}
}
检测 middleware.disable
protected function runRoute(Request $request, Route $route)
{
$request->setRouteResolver(function () use ($route) {
return $route;
});
$this->events->dispatch(new Events\RouteMatched($route, $request));
return $this->prepareResponse($request,
// 调用 runRouteWithinStack 方法,执行路由中间件检测和中间件过滤
$this->runRouteWithinStack($route, $request)
);
}
protected function runRouteWithinStack(Route $route, Request $request)
{
// 检测 Laravel 服务容器中有没有绑定 `middleware.disable`,如果绑定了 `middleware.disable`,检测绑定的值是不是 true
$shouldSkipMiddleware = $this->container->bound('middleware.disable') &&
$this->container->make('middleware.disable') === true;
$middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route);
return (new Pipeline($this->container))
->send($request)
->through($middleware)
->then(function ($request) use ($route) {
return $this->prepareResponse(
$request, $route->run()
);
});
}
获取路由中间件数组
protected function runRouteWithinStack(Route $route, Request $request)
{
$shouldSkipMiddleware = $this->container->bound('middleware.disable') &&
$this->container->make('middleware.disable') === true;
// 执行 gatherRouteMiddleware 方法获取路由中间件数组
$middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route);
return (new Pipeline($this->container))
->send($request)
->through($middleware)
->then(function ($request) use ($route) {
return $this->prepareResponse(
$request, $route->run()
);
});
}
讲在最后
关于 gatherRouteMiddleware 方法
我们自己写的控制器类的实例化,方法名的获取,全部在此方法中执行。具体内容较为复杂,将放在下一章进行讲解。