Laravel源码解析之路由的使用和示例详解


Posted in PHP onSeptember 27, 2018

前言

我的解析文章并非深层次多领域的解析攻略。但是参考着开发文档看此类文章会让你在日常开发中更上一层楼。

废话不多说,我们开始本章的讲解。

入口

Laravel启动后,会先加载服务提供者、中间件等组件,在查找路由之前因为我们使用的是门面,所以先要查到Route的实体类。

注册

第一步当然还是通过服务提供者,因为这是laravel启动的关键,在 RouteServiceProvider 内加载路由文件。

protected function mapApiRoutes()
{
  Route::prefix('api')
     ->middleware('api')
     ->namespace($this->namespace) // 设置所处命名空间
     ->group(base_path('routes/api.php')); //所得路由文件绝对路径
}

首先require是不可缺少的。因路由文件中没有命名空间。 Illuminate\Routing\Router 下方法

protected function loadRoutes($routes)
{
  if ($routes instanceof Closure) {
    $routes($this);
  } else {
    $router = $this;

    require $routes;
  }
}

随后通过路由找到指定方法,依旧是 Illuminate\Routing\Router 内有你所使用的所有路由相关方法,例如get、post、put、patch等等,他们都调用了统一的方法 addRoute

public function addRoute($methods, $uri, $action)
{
  return $this->routes->add($this->createRoute($methods, $uri, $action));
}

之后通过 Illuminate\Routing\RouteCollection addToCollections 方法添加到集合中

protected function addToCollections($route)
{
  $domainAndUri = $route->getDomain().$route->uri();

  foreach ($route->methods() as $method) {
    $this->routes[$method][$domainAndUri] = $route;
  }

  $this->allRoutes[$method.$domainAndUri] = $route;
}

添加后的结果如下图所示

Laravel源码解析之路由的使用和示例详解

实例化

依旧通过反射加载路由指定的控制器,这个时候build的参数$concrete = App\Api\Controllers\XxxController

public function build($concrete)
{
  // If the concrete type is actually a Closure, we will just execute it and
  // hand back the results of the functions, which allows functions to be
  // used as resolvers for more fine-tuned resolution of these objects.
  if ($concrete instanceof Closure) {
    return $concrete($this, $this->getLastParameterOverride());
  }
  
  $reflector = new ReflectionClass($concrete);
  // If the type is not instantiable, the developer is attempting to resolve
  // an abstract type such as an Interface of Abstract Class and there is
  // no binding registered for the abstractions so we need to bail out.
  if (! $reflector->isInstantiable()) {
    return $this->notInstantiable($concrete);
  }
  
    
  $this->buildStack[] = $concrete;

  $constructor = $reflector->getConstructor();
  // If there are no constructors, that means there are no dependencies then
  // we can just resolve the instances of the objects right away, without
  // resolving any other types or dependencies out of these containers.
  if (is_null($constructor)) {
  
      array_pop($this->buildStack);
  
      return new $concrete;
  }

  $dependencies = $constructor->getParameters();
  // Once we have all the constructor's parameters we can create each of the
  // dependency instances and then use the reflection instances to make a
  // new instance of this class, injecting the created dependencies in.
  $instances = $this->resolveDependencies(
    $dependencies
  );

  array_pop($this->buildStack);
  
  return $reflector->newInstanceArgs($instances);
}

这时将返回控制器的实例,下面将通过url访问指定方法,一般控制器都会继承父类 Illuminate\Routing\Controller ,laravel为其设置了别名 BaseController

public function dispatch(Route $route, $controller, $method)
{
  
  $parameters = $this->resolveClassMethodDependencies(
    $route->parametersWithoutNulls(), $controller, $method
  );

  if (method_exists($controller, 'callAction')) {

      return $controller->callAction($method, $parameters);
  }
    
  return $controller->{$method}(...array_values($parameters));
}

Laravel通过controller继承的callAction去调用子类的指定方法,也就是我们希望调用的自定义方法。

public function callAction($method, $parameters)
{
  return call_user_func_array([$this, $method], $parameters);
}

致谢

感谢你看到这里,本篇文章源码解析靠个人理解。如有出入请拍砖。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php之字符串变相相减的代码
Mar 19 PHP
PHP 采集程序 常用函数
Dec 18 PHP
php strlen mb_strlen计算中英文混排字符串长度
Jul 10 PHP
PHP查询MySQL大量数据的时候内存占用分析
Jul 22 PHP
php中cookie实现二级域名可访问操作的方法
Nov 11 PHP
PHP 生成N个不重复的随机数
Jan 21 PHP
Yii数据读取与跳转参数传递用法实例分析
Jul 12 PHP
ThinkPHP和UCenter接口冲突的解决方法
Jul 25 PHP
Yii2中事务的使用实例代码详解
Sep 07 PHP
PHP小偷程序的设计与实现方法详解
Oct 15 PHP
PHP实现动态获取函数参数的方法示例
Apr 02 PHP
PHP学习记录之数组函数
Jun 01 PHP
php实现有序数组旋转后寻找最小值方法
Sep 27 #PHP
PHP实现SMTP邮件的发送实例
Sep 27 #PHP
ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
Sep 26 #PHP
thinkPHP利用ajax异步上传图片并显示、删除的示例
Sep 26 #PHP
多个Laravel项目如何共用migrations详解
Sep 25 #PHP
php中上传文件的的解决方案
Sep 25 #PHP
PHP调用微博接口实现微博登录的方法示例
Sep 22 #PHP
You might like
php后退一页表单内容保存实现方法
2012/06/17 PHP
jQuery 剧场版 你必须知道的javascript
2009/05/27 Javascript
JavaScript 学习小结(适合新手参考)
2009/07/30 Javascript
Ext中下拉列表ComboBox组件store数据格式用法介绍
2013/07/15 Javascript
Javascript中的数组常用方法解析
2016/06/17 Javascript
seajs模块之间依赖的加载以及模块的执行
2016/10/21 Javascript
Bootstrap框架建立树形菜单(Tree)的实例代码
2017/10/30 Javascript
JavaScript实现图片懒加载的方法分析
2018/07/05 Javascript
jQuery动态操作表单示例【基于table表格】
2018/12/06 jQuery
vue axios封装及API统一管理的方法
2019/04/18 Javascript
vue router总结 $router和$route及router与 router与route区别
2019/07/05 Javascript
微信小程序商品详情页底部弹出框
2019/11/22 Javascript
JavaScript 引用类型实例详解【数组、对象、严格模式等】
2020/05/13 Javascript
js实现3D粒子酷炫动态旋转特效
2020/09/13 Javascript
HTML元素拖拽功能实现的完整实例
2020/12/04 Javascript
在Django中限制已登录用户的访问的方法
2015/07/23 Python
Python批量更改文件名的实现方法
2017/10/29 Python
Python爬虫实战之12306抢票开源
2019/01/24 Python
Python实现图片转字符画的代码实例
2019/02/22 Python
windows下安装Python虚拟环境virtualenvwrapper-win
2019/06/14 Python
python批量下载抖音视频
2019/06/17 Python
200行python代码实现2048游戏
2019/07/17 Python
Python将列表中的元素转化为数字并排序的示例
2019/12/25 Python
实例讲解Python 迭代器与生成器
2020/07/08 Python
如何利用Python 进行边缘检测
2020/10/14 Python
前端隐藏出边界内容的实现方法
2016/04/14 HTML / CSS
清除canvas画布内容(点擦除+线擦除)
2020/08/12 HTML / CSS
最新党员思想汇报
2014/01/01 职场文书
大学毕业感言
2014/01/10 职场文书
机械机修工岗位职责
2014/08/03 职场文书
股东合作协议书
2014/09/12 职场文书
写给女朋友的检讨书
2015/05/06 职场文书
酒桌上的开场白
2015/06/01 职场文书
2015年中秋晚会主持词
2015/07/01 职场文书
升学宴来宾致辞
2015/07/27 职场文书
Win11电源已接通但未充电怎么办?Win11电源已接通未充电的解决方法
2022/04/05 数码科技