前言
上一节,我们对标签的选择方面做了一些优化,使得标签的选择更加合理。这节我们来看看 service container 。
说明
开发环境:Windows 7
Laravel 版本: 5+
IDE: Phpstorm
第25节了,我们讲了很多东西,但是还没涉及过 service container ,下面我们讲一下这个到底是什么。
所谓的 Service Container 是一个管理类依赖或者说依赖注入的一个管理器。什么是“依赖注入”,先说“依赖”,一提“依赖”,那必须参与者大于等于2才能形成“依赖”关系,对于类也一样,一个类可能会用到另一个类,也就是产生了依赖的情况;“注入”是什么鬼,英文是“injected”,或者你知道“注射”,在医院,你得了什么病,需要什么要,给你打什么针,输什么液,都要看你具体的病情病症,然后再给你“注入”这些药物。那么合起来“依赖注入”,就是说什么时候需要这个“依赖”关系,什么时候“注入”。
具体在编程中,依赖注入的方式是通过构造函数传参或者 setter 方法来实现。
打开 routes.php ,这里放着我们所有的路由。在文件中添加一个路由:
Route::get('bar',function(Bar $bar){ dd($bar);});
有点编程经验的同学都知道,这个路由是找不到 bar 类的,因为我们压根就没定义过这个类,运行的话肯定会报错。(就不用试验了吧,你可以自己试验。)
但是我们在这个路由上面再添加一个 bar 类,情况就不一样了:
class Bar{}
我的网页上打印的是 “bar {#143}” ,应该是 $bar 的地址之类的。
但是你有没有发现,我们并没有显式的给那个闭包方法提供一个 bar 类的实例化对象,例如如下:
$bar = new Bar();
之类的语句,但是 Laravel 能找到那个类。
这就是 Service Container 的功能所在,它会通过 php 的一个核心机制“反射”来递归查找该类,然后,Service Container 会自动绑定(binding)该类。
那么有自动就有手动,如果想手动绑定(binding)的话,也可以:
App::bind('Bar',function(){ return new Bar();});
添加了上面的代码之后,你就已经通过 App 类的静态方法 bind() 绑定了那个类。还是一开始那句话,你即使不绑定,Laravel 会帮你绑定。
当你谢了一个接口需要实现的时候,这时候,可以通过绑定来把接口绑定到要实现该接口的类上。比如说:
interface BarInterface{}class Bar implements BarInterface{}Route::get('bar',function(BarInterface $bar){ dd($bar);});
此时你怎么能让 Service Container 知道你的类 Bar 实现 BarInterface 呢?看下面:
interface BarInterface{}class Bar implements BarInterface{}App:bind('BarInterface','Bar');Route::get('bar',function(BarInterface $bar){ dd($bar);});
或者:
interface BarInterface{}class Bar implements BarInterface{}App:bind('BarInterface','Bar');Route::get('bar',function(){ $bar = App::make(['BarInterface']); dd($bar);});
就这么简单。
当初我们在学习 Laravel 的路由的时候,不知道你还有无印象,为什么教程里面教的是:
Route::get('/home', 'HomeController@index');
而最开始的 routes.php 里面却是这样的式儿的:
Route::get('/', function () { return view('welcome'); });
其实他们的功能都一样,只不过为了体现 MVC 的理念,各司其职,写到各自的类中,显得整齐。
今天的内容其实就是想告诉我们 Laravel 的 Service Container 这个容器,它的用途和功能。它基于反射机制进行递归查找类,你可以手动,也可以自动,根据自己的需求来。更多的内容可以参考官方文档: Service Container。