php+laravel依赖注入知识点总结

laravel容器包含控制反转和依赖注入,使用起来就是,先把对象bind好,需要时可以直接使用make来取就好。

通常我们的调用如下。

$config = $container->make('config');
$connection = new Connection($this->config);

比较好理解,这样的好处就是不用直接 new 一个实例了,方法传值没啥改变,还可以多处共享此实例。

但这跟依赖注入有什么关系,真正的依赖注入是不需给方法传递任何参数值,只需要指明方法参数类型,代码自动查找关系依赖自动注入。

这个特性在 laravel 的 Controller、Job 等处可以体现,如下:

class TestController extends Controller
{
public function anyConsole(Request $request, Auth $input)
{
//todo
}
}

我们来看下他是怎么实现自动依赖注入的:

由 index.php 调用 Kernel ,经过多层 Kernel 管道调用,再到 Router ,经过多层中间件管道调用。最终定位到

Illuminate/Routing/Route.php 第124行。

public function run(Request $request)
{
$this->container = $this->container ?: new Container;
try {
if (! is_string($this->action['uses'])) {
return $this->runCallable($request);
}

if ($this->customDispatcherIsBound()) {
return $this->runWithCustomDispatcher($request);
}

return $this->runController($request);
} catch (HttpResponseException $e) {
return $e->getResponse();
}
}

判断 $this->action['uses'](格式行如:\App\Http\Controller\Datacenter\RealTimeController@anyConsole)是否字符串, $this->customDispatcherIsBound判断是否绑定了用户自定义路由。然后跳转到 $this->runController($request)。

protected function runController(Request $request)
{
list($class, $method) = explode('@', $this->action['uses']);

$parameters = $this->resolveClassMethodDependencies(
$this->parametersWithoutNulls(), $class, $method
);

if (! method_exists($instance = $this->container->make($class), $method)) {
throw new NotFoundHttpException;
}

return call_user_func_array([$instance, $method], $parameters);
}

$this->resolveClassMethodDependencies 这个方法一看名字就知道是我们要找的方法。$this->parametersWithoutNulls()是过滤空字符,$class、$method分别行如:\App\Http\Controller\Datacenter\RealTimeController 与 anyConsole。

protected function resolveClassMethodDependencies(array $parameters, $instance, $method)
{
if (! method_exists($instance, $method)) {
return $parameters;
}

return $this->resolveMethodDependencies(
$parameters, new ReflectionMethod($instance, $method)
);
}

new ReflectionMethod($instance, $method) 是拿到类方法的反射对象,参见文档:http://www.php.net/manual/zh/class.reflectionmethod.php

下面跳转到Illuminate/Routing/RouteDependencyResolverTrait.php 第54行。

public function resolveMethodDependencies(array $parameters, ReflectionFunctionAbstract $reflector)
{
$originalParameters = $parameters;

foreach ($reflector->getParameters() as $key => $parameter) {
$instance = $this->transformDependency(
$parameter, $parameters, $originalParameters
);

if (! is_null($instance)) {
$this->spliceIntoParameters($parameters, $key, $instance);
}
}

return $parameters;
}

通过反射类方法得到类参数数组,然后遍历传递给 $this->transformDependency 方法。如果实例获取不到则调用 $this->spliceIntoParameters 清楚该参数。

protected function transformDependency(ReflectionParameter $parameter, $parameters, $originalParameters)
{
$class = $parameter->getClass();
if ($class && ! $this->alreadyInParameters($class->name, $parameters)) {
return $this->container->make($class->name);
}
}

终于看到了容器的影子,没错最终对象还是通过容器的 make 方法取出来的。至此参数就构造好了,然后最终会被 runController 方法的 call_user_func_array 回调。

总结:

1. 依赖注入原理其实就是利用类方法反射,取得参数类型,然后利用容器构造好实例。然后再使用回调函数调起。

2. 注入对象构造函数不能有参数。否则会报错。Missing argument 1

3. 依赖注入故然好,但它必须要由 Router 类调起,否则直接用 new方式是无法实现注入的。所以这就为什么只有 Controller 、Job 类才能用这个特性了。

以上就是关于php+laravel依赖注入的全部知识点内容,感谢大家的学习和对我们的支持。

(0)

相关推荐

  • thinkphp5.1框架容器与依赖注入实例分析

    本文实例讲述了thinkphp5.1框架容器与依赖注入.分享给大家供大家参考,具体如下: 容器----/thinkphp/library/think/Container.php 依赖注入:将对象类型的数据,以参数的方式传到方法中(解决向类中的方法传对象的问题) 绑定一个类到容器: public function bindClass() { //把一个类放到容器中:相当于注册到容器中 \think\Container::set('tmp(别名)','\app\common\Temp(实例)');

  • php中的依赖注入实例详解

    本文实例讲述了php中的依赖注入.分享给大家供大家参考,具体如下: 依赖注入是一种允许我们从硬编码的依赖中解耦出来,从而在运行时或者编译时能够修改的软件设计模式. 我到现在依然不大明白上面"依赖注入"的定义是什么-- 有兴趣可以参考下<PHP之道>上面对"依赖注入"的 解释. http://laravel-china.github.io/php-the-right-way/#dependency_injection 简而言之就是可以让我们在类的方法中更加

  • php反射学习之依赖注入示例

    本文实例讲述了php反射学习之依赖注入.分享给大家供大家参考,具体如下: 先看代码: <?php if (PHP_SAPI != 'cli') { exit('Please run it in terminal!'); } if ($argc < 3) { exit('At least 2 arguments needed!'); } $controller = ucfirst($argv[1]) . 'Controller'; $action = 'action' . ucfirst($ar

  • php依赖注入知识点详解

    引言 你知道什么是依赖注入吗?依赖注入(DI)的概念虽然听起来很深奥,但是如果你用过一些新兴的php框架的话,对于DI一定不陌生,因 为它们多多少少都用到了依赖注入来处理类与类之间的依赖关系. php中传递依赖关系的三种方案 其实要理解DI,首先要明白在php中如何传递依赖关系. 第一种方案,也是最不可取的方案,就是在A类中直接用new关键词来创建一个B类,如下代码所示: <?php class A { public function __construct() { $b = new B();

  • php+laravel依赖注入知识点总结

    laravel容器包含控制反转和依赖注入,使用起来就是,先把对象bind好,需要时可以直接使用make来取就好. 通常我们的调用如下. $config = $container->make('config'); $connection = new Connection($this->config); 比较好理解,这样的好处就是不用直接 new 一个实例了,方法传值没啥改变,还可以多处共享此实例. 但这跟依赖注入有什么关系,真正的依赖注入是不需给方法传递任何参数值,只需要指明方法参数类型,代码自

  • spring依赖注入知识点分享

    spring与IoC IoC:控制反转,将由代码操纵的对象控制权,交给第三方容器,反转给第三方容器.这种对象依赖的关系管理方式,称作 IoC.IoC是一个思想,概念.比较 著名的两种方式: DL(Dependency Lookup)依赖查找,典型的是JNDI.java名称与服务接口. DI(Dependency Injection)依赖注入.是目前最优秀的接耦合方式.典型应用spring. spring的DI 依赖注入,即:为属性赋值. xml实现 1)设值注入 底层调用属性的setter方法进

  • ASP.NET Core 过滤器中使用依赖注入知识点总结

    如何给过滤器ActionFilterAttribute也用上构造函数注入呢? 一般自定义的过滤器直接用特性方式标识就能使用 [ContentFilter] 因为构造函数在使用的时候要求传参,然后我们可以使用这个 ServiceFilter 在ASP.NET Core里,我们可以使用ServiceFilter来完成这个需求. ServiceFilter允许我们解析一个已经添加IoC容器的服务,因此我们需要把ContentFilter注册一下. services.AddScoped<ContentF

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

    前言 众所周知,php的框架数不胜数,近几年,一个以优雅著称的框架,渐渐被国内phper所知道,并且开始使用,但是larave有一个很明显的缺点就是,他的文档内容少的可怜. 本文将给大家详细介绍关于Laravel依赖注入的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 在 Laravel 的控制器的构造方法或者成员方法,都可以通过类型约束的方式使用依赖注入,如: public function store(Request $request) { //TODO } 这里

  • Laravel实现构造函数自动依赖注入的方法

    本文实例讲述了Laravel实现构造函数自动依赖注入的方法.分享给大家供大家参考,具体如下: 在Laravel的构造函数中可以实现自动依赖注入,而不需要实例化之前先实例化需要的类,如代码所示: <?php namespace Lio\Http\Controllers\Forum; use Lio\Forum\Replies\ReplyRepository; use Lio\Forum\Threads\ThreadCreator; use Lio\Forum\Threads\ThreadCreat

  • laravel框架中你所用到的依赖注入详解

    前言 用Laravel开发前前后后有2个月左右了,之前一直写Java,就像找到Java和PHP之前的共同点,用Java的某些原理去理解PHP会发现还是有很多共通之处的.Java的依赖注入已经是一个很常见的概念了,Spring框架主要就是解决了这一点,在PHP的laravel框架中,也出现了依赖注入的方式. 依赖注入就控制反转的一种是实现方式,面向对象的特征的重要体现,那么依赖注入中什么是依赖呢,这点用Java开发的人很多都能理解.笼统的说依赖就是一种联系,变量和实现的联系.有关于依赖注入的理解之

  • PHP依赖注入容器知识点浅析

    依赖注入容器理解 耦合 一个好的代码结构设计一定是松耦合的,这也是很多通用设计模式的宗旨,就是把分散在各处的同一个功能的代码汇聚到一起,形成一个模块,然后在不同模块之间通过一些细小的.明确的渠道进行沟通. 在实践中,不同功能和模块之间的互相依赖是不可避免的,而如何处理好这些依赖之间的关系则是代码结构能否变得美好的关键. <?php class User { public function register($user) { // 注册操作 ... // 发送确认邮件 $notify = new

  • 详解Laravel框架的依赖注入功能

    概述 任何时候,你在一个控制器类中请求一个依赖,这个服务容器负责: 1.自动地在构造函数中检测依赖关系 2.如果需要构建这个依赖关系 3.通过构造函数创建对象形成依赖关系 来看一个非常简单的例子. <?php namespace App\Http\Controllers; use App\User; use App\Repositories\UserRepository; use App\Http\Controllers\Controller; class UserController exte

  • 对PHP依赖注入的理解实例分析

    本文实例讲述了对PHP依赖注入的理解.分享给大家供大家参考,具体如下: 看Laravel的IoC容器文档只是介绍实例,但是没有说原理,之前用MVC框架都没有在意这个概念,无意中在phalcon的文档中看到这个详细的介绍,感觉豁然开朗,复制粘贴过来,主要是好久没有写东西了,现在确实很懒变得! 首先,我们假设,我们要开发一个组件命名为SomeComponent.这个组件中现在将要注入一个数据库连接. 在这个例子中,数据库连接在component中被创建,这种方法是不切实际的,这样做的话,我们将不能改

随机推荐