• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    Laravel源码解析之路由的使用和示例详解

    前言

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

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

    入口

    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;
    }

    添加后的结果如下图所示

    实例化

    依旧通过反射加载路由指定的控制器,这个时候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);
    }

    致谢

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

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

    您可能感兴趣的文章:
    • Laravel框架源码解析之入口文件原理分析
    • Laravel框架源码解析之反射的使用详解
    • 通过源码解析Laravel的依赖注入
    • Laravel框架学习笔记(二)项目实战之模型(Models)
    • laravel model模型定义实现开启自动管理时间created_at,updated_at
    • laravel model模型处理之修改查询或修改字段时的类型格式案例
    • Laravel5.1 框架模型工厂ModelFactory用法实例分析
    • Laravel 5框架学习之模型、控制器、视图基础流程
    • Laravel模型事件的实现原理详解
    • Laravel模型间关系设置分表的方法示例
    • laravel学习教程之关联模型
    • Laravel框架源码解析之模型Model原理与用法解析
    上一篇:php实现有序数组旋转后寻找最小值方法
    下一篇:浅析php如何实现爬取数据原理
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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