前言 只為學習
Illuminate\Routing\Router 分析
1. 引入
use Closure;//php 匿名類
use ArrayObject;//
use JsonSerializable;//
use Illuminate\Support\Str;//框架支援的str類
use Illuminate\Http\Request;//框架請求類
use Illuminate\Http\Response;//框架響應類
use Illuminate\Http\JsonResponse;//框架json響應類
use Illuminate\Support\Collection;//框架支援的集合類
use Illuminate\Container\Container;//框架容器基類
use Illuminate\Database\Eloquent\Model;//框架資料庫模型基類
use Illuminate\Support\Traits\Macroable;//框架 Macroable Traits
use Illuminate\Contracts\Support\Jsonable;//框架契約json介面
use Illuminate\Contracts\Events\Dispatcher;//框架契約時間排程介面
use Illuminate\Contracts\Support\Arrayable;//框架契約陣列介面
use Illuminate\Contracts\Support\Responsable;//框架契約響應體介面
use Illuminate\Contracts\Routing\BindingRegistrar;//框架契約路由繫結暫存器介面
use Psr\Http\Message\ResponseInterface as PsrResponseInterface;//
use Illuminate\Contracts\Routing\Registrar as RegistrarContract;//框架契約路由暫存器介面
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;//
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
2. 宣告router類 實現介面
class Router implements RegistrarContract, BindingRegistrar
{
use Macroable {
__call as macroCall;//使用Macroable Traits 並且重名稱__call 方法
}
/**
* The event dispatcher instance.
* 事件排程器例項
* @var \Illuminate\Contracts\Events\Dispatcher
*/
protected $events;
/**
* The IoC container instance.
* 容器例項
* @var \Illuminate\Container\Container
*/
protected $container;
/**
* The route collection instance.
* 路由集合例項
* @var \Illuminate\Routing\RouteCollection
*/
protected $routes;
/**
* The currently dispatched route instance.
* 當前路由
* @var \Illuminate\Routing\Route
*/
protected $current;
/**
* The request currently being dispatched.
* 當前請求
* @var \Illuminate\Http\Request
*/
protected $currentRequest;
/**
* All of the short-hand keys for middlewares.
* 中介軟體
* @var array
*/
protected $middleware = [];
/**
* All of the middleware groups.
* 中介軟體組
* @var array
*/
protected $middlewareGroups = [];
/**
* The priority-sorted list of middleware.
*
* Forces the listed middleware to always be in the given order.
* 強制列出的中介軟體始終按給定順序排列。
* @var array
*/
public $middlewarePriority = [];
/**
* The registered route value binders.
* 註冊路由繫結
* @var array
*/
protected $binders = [];
/**
* The globally available parameter patterns.
* 全域性可用引數模式
* @var array
*/
protected $patterns = [];
/**
* The route group attribute stack.
* 路由組屬性堆疊。
* @var array
*/
protected $groupStack = [];
/**
* All of the verbs supported by the router.
* 路由器支援的所有動作
* @var array
*/
public static $verbs = ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'];
3. 構造方法
//註冊一個新的router 例項
public function __construct(Dispatcher $events, Container $container = null)
{
$this->events = $events;
$this->routes = new RouteCollection;
$this->container = $container ?: new Container;
}
4. get 向路由器註冊新的get 路由
1、addRoute
public function get($uri, $action = null)
{
return $this->addRoute(['GET', 'HEAD'], $uri, $action);
}
5. post 向路由器註冊新的post 路由
1、addRoute
public function post($uri, $action = null)
{
return $this->addRoute('POST', $uri, $action);
}
6. put 向路由器註冊新的put 路由
1、addRoute
public function put($uri, $action = null)
{
return $this->addRoute('PUT', $uri, $action);
}
7. patch 向路由器註冊新的patch 路由
1、addRoute
public function patch($uri, $action = null)
{
return $this->addRoute('PATCH', $uri, $action);
}
8. delete 向路由器註冊新的delete路由
1、addRoute
public function delete($uri, $action = null)
{
return $this->addRoute('DELETE', $uri, $action);
}
9. options 向路由器註冊新的options 路由
1、addRoute
public function options($uri, $action = null)
{
return $this->addRoute('OPTIONS', $uri, $action);
}
10. any 註冊響應所有動詞的新路由。
1、addRoute
public function any($uri, $action = null)
{
return $this->addRoute(self::$verbs, $uri, $action);
}
11. fallback 註冊回退路由
1、addRoute
public function fallback($action)
{
$placeholder = 'fallbackPlaceholder';
return $this->addRoute(
'GET', "{{$placeholder}}", $action
)->where($placeholder, '.*')->fallback();
}
12. redirect 建立重定向路由
public function redirect($uri, $destination, $status = 302)
{
return $this->any($uri, '\Illuminate\Routing\RedirectController')
->defaults('destination', $destination)
->defaults('status', $status);
}
13. permanentRedirect 建立從一個URI到另一個URI的永久重定向
1、redirect
public function permanentRedirect($uri, $destination)
{
return $this->redirect($uri, $destination, 301);
}
14. view 註冊返回檢視的新路由。
public function view($uri, $view, $data = [])
{
return $this->match(['GET', 'HEAD'], $uri, '\Illuminate\Routing\ViewController')
->defaults('view', $view)
->defaults('data', $data);
}
15. match 註冊多個動作的新路由
1、addRoute
public function match($methods, $uri, $action = null)
{
return $this->addRoute(array_map('strtoupper', (array) $methods), $uri, $action);
}
16. resources 註冊一個資源控制器陣列。
1、resource
public function resources(array $resources, array $options = [])
{
foreach ($resources as $name => $controller) {
$this->resource($name, $controller, $options);
}
}
17. resource 新增資源路由到控制器
public function resource($name, $controller, array $options = [])
{
if ($this->container && $this->container->bound(ResourceRegistrar::class)) {
$registrar = $this->container->make(ResourceRegistrar::class);
} else {
$registrar = new ResourceRegistrar($this);// Illuminate\Routing\ResourceRegistrar
}
// \Illuminate\Routing\PendingResourceRegistration
return new PendingResourceRegistration(
$registrar, $name, $controller, $options
);
}
18. apiResources 註冊api路由陣列
public function apiResources(array $resources, array $options = [])
{
foreach ($resources as $name => $controller) {
$this->apiResource($name, $controller, $options);
}
}
19. apiResource 註冊api路由到控制器
1、resource
public function apiResource($name, $controller, array $options = [])
{
$only = ['index', 'show', 'store', 'update', 'destroy'];
if (isset($options['except'])) {
$only = array_diff($only, (array) $options['except']);
}
return $this->resource($name, $controller, array_merge([
'only' => $only,
], $options));
}
20. group 建立路由組
1、updateGroupStack
2、
public function group(array $attributes, $routes)
{
$this->updateGroupStack($attributes);// 更新堆疊
$this->loadRoutes($routes);
array_pop($this->groupStack);//刪除最後一個堆疊資料
}
21. updateGroupStack
1、
protected function updateGroupStack(array $attributes)
{
if (! empty($this->groupStack)) {
$attributes = $this->mergeWithLastGroup($attributes);
}
$this->groupStack[] = $attributes;
}
22. mergeWithLastGroup 將給定陣列與最後一個組堆疊合併
public function mergeWithLastGroup($new)
{
return RouteGroup::merge($new, end($this->groupStack));
}
23. loadRoutes 載入路由資料
protected function loadRoutes($routes)
{
if ($routes instanceof Closure) {
$routes($this);
} else {
$router = $this;
require $routes;
}
}
24. getLastGroupPrefix 從堆疊上的最後一個組獲取字首
public function getLastGroupPrefix()
{
if (! empty($this->groupStack)) {
$last = end($this->groupStack);
return $last['prefix'] ?? '';
}
return '';
}
25. addRoute
1、createRoute
2、add
public function addRoute($methods, $uri, $action)
{
return $this->routes->add($this->createRoute($methods, $uri, $action));
}
26. createRoute 建立路由
1、actionReferencesController
2、convertToControllerAction
3、newRoute
4、prefix
5、hasGroupStack
6、mergeGroupAttributesIntoRoute
7、addWhereClausesToRoute
protected function createRoute($methods, $uri, $action)
{
//確定操作是否路由到控制器。
if ($this->actionReferencesController($action)) {
//將基於控制器的路由操作新增到運算元組
$action = $this->convertToControllerAction($action);
}
//
$route = $this->newRoute(
$methods, $this->prefix($uri), $action
);
if ($this->hasGroupStack()) {
$this->mergeGroupAttributesIntoRoute($route);
}
$this->addWhereClausesToRoute($route);
return $route;
}
27. actionReferencesController 確定操作是否路由到控制器。
protected function actionReferencesController($action)
{
if (! $action instanceof Closure) {
return is_string($action) || (isset($action['uses']) && is_string($action['uses']));
}
return false;
}
28. convertToControllerAction 將基於控制器的路由操作新增到運算元組
protected function convertToControllerAction($action)
{
if (is_string($action)) {
$action = ['uses' => $action];
}
if (! empty($this->groupStack)) {
$action['uses'] = $this->prependGroupNamespace($action['uses']);
}
$action['controller'] = $action['uses'];
return $action;
}
29. prependGroupNamespace 最後一個組名稱空間前置到use子句上
protected function prependGroupNamespace($class)
{
$group = end($this->groupStack);
return isset($group['namespace']) && strpos($class, '\\') !== 0
? $group['namespace'].'\\'.$class : $class;
}
30. newRoute 建立路由物件
protected function newRoute($methods, $uri, $action)
{
return (new Route($methods, $uri, $action))
->setRouter($this)
->setContainer($this->container);
}
31. prefix 給定的url字首
protected function prefix($uri)
{
return trim(trim($this->getLastGroupPrefix(), '/').'/'.trim($uri, '/'), '/') ?: '/';
}
32. addWhereClausesToRoute 新增條款刪除
protected function addWhereClausesToRoute($route)
{
$route->where(array_merge(
$this->patterns, $route->getAction()['where'] ?? []
));
return $route;
}
33. mergeGroupAttributesIntoRoute 將組堆疊與控制器操作合併
protected function mergeGroupAttributesIntoRoute($route)
{
$route->setAction($this->mergeWithLastGroup($route->getAction()));
}
34. respondWithRoute 返回給定路由返回的響應
1、runRoute
public function respondWithRoute($name)
{
$route = tap($this->routes->getByName($name))->bind($this->currentRequest);
return $this->runRoute($this->currentRequest, $route);
}
35. dispatch 將請求傳送到應用程式。
public function dispatch(Request $request)
{
$this->currentRequest = $request;
return $this->dispatchToRoute($request);
}
36. dispatchToRoute 將請求傳送到路由並返回響應
public function dispatchToRoute(Request $request)
{
return $this->runRoute($request, $this->findRoute($request));
}
37. findRoute 匹配路由
protected function findRoute($request)
{
$this->current = $route = $this->routes->match($request);
$this->container->instance(Route::class, $route);
return $route;
}
38. runRoute 執行路由返回響應
1、prepareResponse
2、runRouteWithinStack
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,
$this->runRouteWithinStack($route, $request)
);
}
39. runRouteWithinStack 在堆疊例項中執行給定的路由
1、gatherRouteMiddleware
2、prepareResponse
protected function runRouteWithinStack(Route $route, Request $request)
{
$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()
);
});
}
40. gatherRouteMiddleware 獲取當前路由中介軟體
public function gatherRouteMiddleware(Route $route)
{
$middleware = collect($route->gatherMiddleware())->map(function ($name) {
return (array) MiddlewareNameResolver::resolve($name, $this->middleware, $this->middlewareGroups);
})->flatten();
return $this->sortMiddleware($middleware);
}
41. sortMiddleware 排序中介軟體
protected function sortMiddleware(Collection $middlewares)
{
return (new SortedMiddleware($this->middlewarePriority, $middlewares))->all();
}
42. prepareResponse 給定值響應例項
public function prepareResponse($request, $response)
{
return static::toResponse($request, $response);
}
43. toResponse
public static function toResponse($request, $response)
{
if ($response instanceof Responsable) {
$response = $response->toResponse($request);
}
if ($response instanceof PsrResponseInterface) {
$response = (new HttpFoundationFactory)->createResponse($response);
} elseif ($response instanceof Model && $response->wasRecentlyCreated) {
$response = new JsonResponse($response, 201);
} elseif (! $response instanceof SymfonyResponse &&
($response instanceof Arrayable ||
$response instanceof Jsonable ||
$response instanceof ArrayObject ||
$response instanceof JsonSerializable ||
is_array($response))) {
$response = new JsonResponse($response);
} elseif (! $response instanceof SymfonyResponse) {
$response = new Response($response);
}
if ($response->getStatusCode() === Response::HTTP_NOT_MODIFIED) {
$response->setNotModified();
}
return $response->prepare($request);
}
44. substituteBindings 將路由繫結替換到路由上
public function substituteBindings($route)
{
foreach ($route->parameters() as $key => $value) {
if (isset($this->binders[$key])) {
$route->setParameter($key, $this->performBinding($key, $value, $route));
}
}
return $route;
}
45. substituteImplicitBindings
public function substituteImplicitBindings($route)
{
ImplicitRouteBinding::resolveForRoute($this->container, $route);
}
46. performBinding 呼叫給定鍵的繫結回撥。
protected function performBinding($key, $value, $route)
{
return call_user_func($this->binders[$key], $value, $route);
}
47. matched 註冊路由匹配的事件偵聽器
public function matched($callback)
{
$this->events->listen(Events\RouteMatched::class, $callback);
}
48. getMiddleware 獲取全域性中介軟體
public function getMiddleware()
{
return $this->middleware;
}
49. aliasMiddleware 設定中介軟體別名
public function aliasMiddleware($name, $class)
{
$this->middleware[$name] = $class;
return $this;
}
50. hasMiddlewareGroup 檢測是否存在中介軟體組中
public function hasMiddlewareGroup($name)
{
return array_key_exists($name, $this->middlewareGroups);
}
51. getMiddlewareGroups 獲取中介軟體組
public function getMiddlewareGroups()
{
return $this->middlewareGroups;
}
52. middlewareGroup 設定中介軟體組
public function middlewareGroup($name, array $middleware)
{
$this->middlewareGroups[$name] = $middleware;
return $this;
}
53. prependMiddlewareToGroup 頭部插入中介軟體組
public function prependMiddlewareToGroup($group, $middleware)
{
if (isset($this->middlewareGroups[$group]) && ! in_array($middleware, $this->middlewareGroups[$group])) {
array_unshift($this->middlewareGroups[$group], $middleware);
}
return $this;
}
54. pushMiddlewareToGroup 尾部插入中介軟體組
public function pushMiddlewareToGroup($group, $middleware)
{
if (! array_key_exists($group, $this->middlewareGroups)) {
$this->middlewareGroups[$group] = [];
}
if (! in_array($middleware, $this->middlewareGroups[$group])) {
$this->middlewareGroups[$group][] = $middleware;
}
return $this;
}
55. bind
public function bind($key, $binder)
{
$this->binders[str_replace('-', '_', $key)] = RouteBinding::forCallback(
$this->container, $binder
);
}
56. model 為萬用字元註冊模型繫結器
public function model($key, $class, Closure $callback = null)
{
$this->bind($key, RouteBinding::forModel($this->container, $class, $callback));
}
57. getBindingCallback 獲取繫結的回撥函式
public function getBindingCallback($key)
{
if (isset($this->binders[$key = str_replace('-', '_', $key)])) {
return $this->binders[$key];
}
}
58. getPatterns 全域性匹配模式
public function getPatterns()
{
return $this->patterns;
}
59. pattern 設定全域性匹配模式
public function pattern($key, $pattern)
{
$this->patterns[$key] = $pattern;
}
60. patterns 批量設定全域性匹配模式
public function patterns($patterns)
{
foreach ($patterns as $key => $pattern) {
$this->pattern($key, $pattern);
}
}
61. hasGroupStack 判斷路由組屬性堆是否存在
public function hasGroupStack()
{
return ! empty($this->groupStack);
}
62. getGroupStack 獲取路由組屬性堆
public function getGroupStack()
{
return $this->groupStack;
}
63. input 獲取當前請求引數
public function input($key, $default = null)
{
return $this->current()->parameter($key, $default);
}
64. getCurrentRequest 獲取當前請求
public function getCurrentRequest()
{
return $this->currentRequest;
}
65. getCurrentRoute 獲取當前請求路由
public function getCurrentRoute()
{
return $this->current();
}
66. current 獲取當前請求路由
public function current()
{
return $this->current;
}
67. has 檢測路由是否存在
public function has($name)
{
$names = is_array($name) ? $name : func_get_args();
foreach ($names as $value) {
if (! $this->routes->hasNamedRoute($value)) {
return false;
}
}
return true;
}
68. currentRouteName 當前路由名稱
public function currentRouteName()
{
return $this->current() ? $this->current()->getName() : null;
}
69. is
public function is(...$patterns)
{
return $this->currentRouteNamed(...$patterns);
}
70. currentRouteNamed 確定當前路由是否符合模式
public function currentRouteNamed(...$patterns)
{
return $this->current() && $this->current()->named(...$patterns);
}
71. currentRouteAction 獲取當前請求路由控制器
public function currentRouteAction()
{
if ($this->current()) {
return $this->current()->getAction()['controller'] ?? null;
}
}
72. uses “currentRouteuses”方法的別名
public function uses(...$patterns)
{
foreach ($patterns as $pattern) {
if (Str::is($pattern, $this->currentRouteAction())) {
return true;
}
}
return false;
}
73. currentRouteUses
public function currentRouteUses($action)
{
return $this->currentRouteAction() == $action;
}
74. auth 為應用程式註冊典型的身份驗證路由
public function auth(array $options = [])
{
$this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
$this->post('login', 'Auth\LoginController@login');
$this->post('logout', 'Auth\LoginController@logout')->name('logout');
if ($options['register'] ?? true) {
$this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
$this->post('register', 'Auth\RegisterController@register');
}
if ($options['reset'] ?? true) {
$this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
$this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
$this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
$this->post('password/reset', 'Auth\ResetPasswordController@reset')->name('password.update');
}
if ($options['verify'] ?? false) {
$this->emailVerification();
}
}
75. emailVerification 註冊郵箱驗證路由
public function emailVerification()
{
$this->get('email/verify', 'Auth\VerificationController@show')->name('verification.notice');
$this->get('email/verify/{id}', 'Auth\VerificationController@verify')->name('verification.verify');
$this->get('email/resend', 'Auth\VerificationController@resend')->name('verification.resend');
}
76. singularResourceParameters 將未對映的全域性資源引數設定為單數
public function singularResourceParameters($singular = true)
{
ResourceRegistrar::singularParameters($singular);
}
77. resourceParameters 設定全域性資源引數對映
public function resourceParameters(array $parameters = [])
{
ResourceRegistrar::setParameters($parameters);
}
78. resourceVerbs 獲取或設定資源URI中使用的謂詞
public function resourceVerbs(array $verbs = [])
{
return ResourceRegistrar::verbs($verbs);
}
79. getRoutes 獲取路由集合例項
public function getRoutes()
{
return $this->routes;
}
80. setRoutes 設定路由集合例項
public function setRoutes(RouteCollection $routes)
{
foreach ($routes as $route) {
$route->setRouter($this)->setContainer($this->container);
}
$this->routes = $routes;
$this->container->instance('routes', $this->routes);
}
81. 魔術方法
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
if ($method === 'middleware') {
return (new RouteRegistrar($this))->attribute($method, is_array($parameters[0]) ? $parameters[0] : $parameters);
}
return (new RouteRegistrar($this))->attribute($method, $parameters[0]);
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結