Laravel 是如何实现用路由去调用控制器方法以及闭包方法
这篇文章写得比较详细。有兴趣的朋友可以点击 这个链接 深入浅出 Laravel 路由执行原理 查看。
话不多说直接上Laravel底层代码: 路径:vendor\laravel\framework\src\Illuminate\Routing\Route.php
<?php
/**
* Create a new Route instance. 创建一个Route实例。
*
* @param array|string $methods
* @param string $uri
* @param \Closure|array $action
* @return void
*/
public function __construct($methods, $uri, $action)
{
$this->uri = $uri;
$this->methods = (array) $methods;
$this->action = $this->parseAction($action);
if (in_array('GET', $this->methods) && ! in_array('HEAD', $this->methods)) {
$this->methods[] = 'HEAD';
}
if (isset($this->action['prefix'])) {
$this->prefix($this->action['prefix']);
}
}
/**
* Parse the route action into a standard array. 将路线动作解析成数组。
*
* @param callable|array|null $action
* @return array
*
* @throws \UnexpectedValueException
*/
protected function parseAction($action)
{
return RouteAction::parse($this->uri, $action);
}
/**
* Run the route action and return the response. 运行route操作并返回响应。
*
* @return mixed
*/
public function run()
{
$this->container = $this->container ?: new Container;
try {
if ($this->isControllerAction()) {
return $this->runController();
}
return $this->runCallable();
} catch (HttpResponseException $e) {
return $e->getResponse();
}
}
/**
* Checks whether the route's action is a controller.
*
* @return bool
*/
protected function isControllerAction() //确定动作是否是控制器
{
return is_string($this->action['uses']);
}
/**
* Run the route action and return the response.
*
* @return mixed
*/
protected function runCallable() //执行动作并且返回 响应
{
$callable = $this->action['uses'];
return $callable(...array_values($this->resolveMethodDependencies(
$this->parametersWithoutNulls(), new ReflectionFunction($this->action['uses'])
)));
}
/**
* Run the route action and return the response.
*
* @return mixed
*
* @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
*/
protected function runController() //执行路由动作并且返回响应
{
return $this->controllerDispatcher()->dispatch( // 将请求分配给指定的控制器和方法。
$this, $this->getController(), $this->getControllerMethod()
);
}
/**
* Get the controller instance for the route.
*
* @return mixed
*/
public function getController() // 获取执行的控制器
{
if (! $this->controller) {
$class = $this->parseControllerCallback()[0];
$this->controller = $this->container->make(ltrim($class, '\\'));
}
return $this->controller;
}
/**
* Get the controller method used for the route.
*
* @return string
*/
protected function getControllerMethod() // 获取控制器执行的方法
{
return $this->parseControllerCallback()[1];
}
/**
* Parse the controller.
*
* @return array
*/
protected function parseControllerCallback() //解析控制器, 分解成控制器类以及操作的方法
{
return Str::parseCallback($this->action['uses']);
}
/**
* Get the dispatcher for the route's controller.
*
* @return \Illuminate\Routing\Contracts\ControllerDispatcher
*/
public function controllerDispatcher() //获取路由控制器的调度程序。
{
if ($this->container->bound(ControllerDispatcherContract::class)) {
return $this->container->make(ControllerDispatcherContract::class);
}
return new ControllerDispatcher($this->container);
}
以上只列出底层的几个方法,想要具体了解实现步骤可以打dd()断点自行体会,要注意打完断点记得清理掉!!!
拆分路由
laravel 的路由主要是放在 项目根目录下的routes文件夹,laravel 已经为我们分配好了api.php 和 web.php 两个路由文件,这显然在我们开发过程中是不够用的。所以我们需要拆分出单独的路由文件,以便我们管理维护路由。
以下都是以拆分web.php为例,API路由同理。
方法一:
- 在 web.php 同目录下新建 web/user.php
2. 在 web.php 里面 require_once (‘web/user.php’); 引入该文件
3.然后就可以直接在user.php 写入路由了
方法二:
- 打开文件: app\Providers\RouteServiceProvider.php
2.修改:boot()方法
public function boot()
{
//匹配通用路由地址
$pattern = __DIR__ . '/../Http/Routes/*.php';
foreach (glob($pattern) as $route) {
require_once $route;
}
parent::boot();
}
- 然后新建文件夹 app\Http\Routes
- 在 app\Http\Routes下建立路由文件 user.php
这样也可以实现路由。
访问: 你的域名/user/login