时间:2021-05-25
前言
众所周知,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.
根据类名可以从容器中获取一开始通过服务提供者绑定的实例。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
本文实例讲述了Laravel实现构造函数自动依赖注入的方法。分享给大家供大家参考,具体如下:在Laravel的构造函数中可以实现自动依赖注入,而不需要实例化之前
Laravel能够自动注入需要的依赖,对于自定义的类和接口是有些不同的。对于类,Laravel可以自动注入,但是接口的话需要创建相应的ServiceProvid
前言Laravel服务器容器:是用于管理类依赖和执行依赖注入的工具。下面我们演示下如何创建服务器提供者,它是Laravel的核心。话不多说了,来一起看看详细的介
Spring的依赖注入Spring主要支持两种依赖注入方式,分别是属性注入和构造函数注入。同时也支持工厂方法注入方式。属性注入属性注入的方式非常简单,即指通过s
在阅读这篇文章之前,大家可以先参阅《理解Spring中的依赖注入和控制反转》一文,了解下依赖注入和控制反转的相关内容。三种依赖注入的方式属性注入,通过sette