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

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    通过源码解析Laravel的依赖注入

    前言

    众所周知,php的框架数不胜数,近几年,一个以优雅著称的框架,渐渐被国内phper所知道,并且开始使用,但是larave有一个很明显的缺点就是,他的文档内容少的可怜。

    本文将给大家详细介绍关于Laravel依赖注入的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。

    在 Laravel 的控制器的构造方法或者成员方法,都可以通过类型约束的方式使用依赖注入,如:

    public function store(Request $request)
    {
     //TODO
    }

    这里 $request 参数就使用了类型约束,Request 是一个类:\Illuminate\Http\Request,表示参数必须是这个类或子类。

    本文通过分析 Laravel 的源码,看为什么方法中不需要传入实例就可以直接使用 Request 呢?只是框架自动帮我们实例化并传参了。

    1.路由定义

    从源头开始看起,在路由定义文件中定义了这么一个路由:

    Route::resource('/role', 'Admin\RoleController');

    这是一个资源型的路由,Laravel 会自动生成增删改查的路由入口。

    本文开头的 store 方法就是一个控制器的方法,图中可见路由定义的 Action 也是:App\Http\Controllers\Admin\RoleController@store

    路由方法解析

    根据路由定义找到控制器和方法,执行具体的方法在 dispatch 方法中实现。

    (文件:vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php)

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

    首先 resolveClassMethodDependencies 方法,“顾名思义”是根据类的方法参数获取依赖对象,然后再调用类的方法并把对象参数注入。

    如果有多个依赖对象,也会 foreach 依次解析出来作为参数注入。

    获取依赖对象示例的代码:

    protected function resolveClassMethodDependencies(array $parameters, $instance, $method)
    {
     if (! method_exists($instance, $method)) {
      return $parameters;
     }
     
     return $this->resolveMethodDependencies(
      $parameters, new ReflectionMethod($instance, $method)
     );
    }

    这里重点就是用到了 PHP 的反射,注意 RelectionMethod 方法,它获取到类的方法参数列表,可以知道参数的类型约束,参数名称等等。

    这里的 $instance 参数就是 RoleController 控制器类,$method 参数就是方法名称 strore.

    2.获取依赖对象的示例

    从方法的参数中获取了依赖对象的约束类型,就可以实例化这个依赖的对象。

    protected function transformDependency(ReflectionParameter $parameter, $parameters)
    {
     $class = $parameter->getClass(); 
     // If the parameter has a type-hinted class, we will check to see if it is already in
     // the list of parameters. If it is we will just skip it as it is probably a model
     // binding and we do not want to mess with those; otherwise, we resolve it here.
     if ($class  ! $this->alreadyInParameters($class->name, $parameters)) {
      return $parameter->isDefaultValueAvailable()
       ? $parameter->getDefaultValue()
       : $this->container->make($class->name);
     }
    }

    根据类名从容器中获取对象,这个绑定对象实例的过程在服务提供者中先定义和了。

    然后把实例化的对象传入到 store 方法中,就可以使用依赖的对象了。

    3.关于 PHP 反射

    举个使用 ReflectionMethod 的例子。

    class Demo
    {
     private $request;
     public function store(Request $request)
     {
     }
    }

    打印出 new ReflectionMethod(Demo::class, ‘store') 的内容如图:

    可以得出这个方法的参数列表,参数的约束类型,如 typeHint,Illuminate\Http\Request.

    根据类名可以从容器中获取一开始通过服务提供者绑定的实例。

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

    您可能感兴趣的文章:
    • php+laravel依赖注入知识点总结
    • laravel框架中你所用到的依赖注入详解
    • Laravel实现构造函数自动依赖注入的方法
    • PHP依赖注入容器知识点浅析
    • php依赖注入知识点详解
    • php中的依赖注入实例详解
    • php反射学习之依赖注入示例
    • PHP依赖注入原理与用法分析
    • 详解Laravel框架的依赖注入功能
    上一篇:phpstorm 正则匹配删除空行、注释行(替换注释行为空行)
    下一篇:Laravel中使用Queue的最基本操作教程
  • 相关文章
  • 

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

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

    通过源码解析Laravel的依赖注入 通过,源码,解析,Laravel,的,