【php】Laravel的“服务容器”和“服务提供者”,哪个是laravel 的核心?
在一些资料中看到说,“服务容器”是laravel 的核心,“服务提供者”也是laravel 的核心。
问题:
1、究竟哪个是核心,还是它们两个组合起来构成了核心?
2、它们两个的关系是什么?
3、它们两个各自的作用是什么的?
4、有“服务容器”,有“服务提供者”,那具体的“服务”在什么地方?打个比方,就是有装饭的锅,有装饭的碗,那饭在什么地方?是在锅里,还是在碗里,还是在田里?
回答
可以去看我的这篇笔记
https://segmentfault.com/a/1190000004965752
摘选
Contracts, ServiceContainer, ServiceProvider, Facades关系
Contracts 合同,契约,也就是接口,定义一些规则,每个实现此接口的都要实现里面的方法
ServiceContainer 实现Contracts,具体的逻辑实现
ServiceProvider ServiceContainer的服务提供者,返回ServiceContainer的实例化,供其他地方使用,可以把它加入到app/config的provider中,会被自动注册到容器中
Facades 简化ServiceProvider的调用方式,而且可以静态调用ServiceContainer中的方法
实现
Contracts接口可以写或不写,这里就不定义了
定义一个ServiceContainer,实现具体的功能
namespace App\Helper;class MyFoo
{
public function add($a, $b)
{
return $a+$b;
}
}
定义一个ServiceProvider供其他地方使用ServiceContain
<?phpnamespace App\Providers;
use App\Helper\MyFoo; //要服务的Container
use Illuminate\Support\ServiceProvider;
use App;
class MyFooServiceProvider extends ServiceProvider
{
public function boot(){}
//注册到容器中
public function register()
{
//可以这么绑定,这需要use App;
App::bind("myfoo",function(){
return new MyFoo();
});
//也可以这么绑定
$this->app->bind("myfoo", function(){
return new MyFoo();
});
}
}
在app/config.php中的providers数组中加入ServiceProvider,让系统自动注册
App\Providers\MyFooServiceProvider::class,
这时候就可以使用了,假设在控制器中使用
public function two($id=null){
//从系统容器中获取实例化对象
$myfoo = App::make("myfoo");
echo $myfoo->add(1,2);
}
这样太麻烦,还需要用make来获取对象,为了简便,就可以使用门面功能,定义门面MyFooFacade
namespace App\Facades;use Illuminate\Support\Facades\Facade;
class MyFooFacade extends Facade
{
protected static function getFacadeAccessor()
{
//这里返回的是ServiceProvider中注册时,定义的字符串
return 'myfoo';
}
}
在控制器里就可以直接调用了
use App\Facades\MyFooFacade;public function two($id=null)
{
//从系统容器中获取实例化对象
$myfoo = App::make("myfoo");
echo $myfoo->add(1,2);
//使用门面
echo MyFooFacade::add(4,5);
}
总的来说,自定义了一个类,为了方便在其他别处使用,便可以使用服务提供者和门面
Laravel中Container就好似一个大水桶,是核心,每一个Service就好似装满一种饮料的瓶瓶罐罐,Service Provider就好似连接饮料瓶和水桶的插管,可要可不要,直接往水桶里倒也行,虽然这样不讲究。。想去大水桶喝饮料去(一次请求来了),Facade就好似是水瓢帮你从水桶里舀水,当然不要也行直接用手,虽然不卫生,所以Facade可要可不要。
奥,对了,还有一个Contract,主要是为了好管理每一个Service,在碳酸水Service里,那也有分类,可乐百事被一个Contract拴在一起,雪碧美年达被另一个Contract拴在一起,主要也是为了好测试好替换而已。。
总之,Laravel这几个主要概念也就干了这些事,没啥高深的。
如有不全面的请留言。
服务容器是核心。
拿操作系统做个比方,服务容器是内核,服务对象是程序,服务是程序安装包,服务提供者是程序安装光盘。
服务是一个比较难理解的概念,你只需要知道你调用服务时会返回一个服务对象供你操作。大部分情况下可以把服务理解成是一个返回对象的闭包。
多年以前是没有服务这个概念的,比如Codeigniter这个框架,它有一个$CI对象,你可以把它理解成一个服务容器吧。然后在框架的启动过程中,它会初始化一些对象,然后把这些对象绑定到$CI对象中去,这些对象可以理解成服务对象。
但是问题就产生了,Codeigniter中绑定的服务对象数量不多还好,一旦数量多起来,比如说几百个,那么系统会需要初始化几百个对象并绑定到$CI中去。但是很可能一次Http请求用到的只有其中十分之一的对象,那么其他用不到的对象的初始化不就浪费了么?
$CI = new container();//可以当成服务容器$log = new log();//可以当成服务对象
$CI->log = $log;//每次执行都要初始化并绑定
$CI->log->write('xxxx');//很可能用不上
那么怎么解决呢,答案是用闭包,通过闭包把生成对象的代码封装起来。只有当你真正需要这个对象的时候,你去调用这个闭包才会生成并返回一个对象。
$CI = new container();//同样服务容器$CI->bind('log', functon($CI){
return new log();
});//绑定了一个返回服务对象的闭包
$CI->log->write('xxx');//只有当调用时才会真正生成log对象
简直是个天才的想法,但是如何让这些闭包管理起来更方便呢?服务提供者就出现了。
写不下去了,改日再补充吧。
关于这个推荐一篇博文
laravel 学习笔记 —— 神奇的服务容器
简单的说,“服务容器”就是“服务提供者”提供的服务的容器,“服务容器”通过“服务提供者”来获取服务。
一个laravel应用就是一个“服务容器”,整个框架提供的各种功能由“服务提供者”提供并注入到“服务容器”中。每一个“服务提供者”里register
的方法里面使用bind
邦定某个对象到一个变量,那个对象就是真正提供服务的对象。
服务容器和服务提供者的核心是降低查询数据库的rps参数
from https://segmentfault.com/q/1010000000602732
应该是服务容器吧,laravel 的核心最重要的功能就是提供一个服务容器,而所有的比如request route等组件都是通过服务容器生产出来的,而服务容器提供者就是告诉服务容器需要生产哪些组件。
相关扩展阅读:
laravel Ioc Container (Service Provider 服务容器)的魔力之一:automatic dependency resolution(自动依赖解析、依赖映射)
Laravel自动依赖解析的背后实现——PHP映射解析(reflection apireflection class)功能
php传参类型声明(type declaration)及常见的依赖注入(dependency injection)
以上是 【php】Laravel的“服务容器”和“服务提供者”,哪个是laravel 的核心? 的全部内容, 来源链接: utcz.com/a/98319.html