看到laravel手册的服务容器和提供器模块,概念有些模糊,网上搜索+动手实践了一番,记录理解。
laravel框架默认加载了很多的服务,一个服务就是一个类,比如Auth,Cache,Route等等。如果想自定义一个服务怎么办,很简单,自己创建一个类然后再绑定就行。服务容器和服务提供器是没有直接关系的,一般都是按照什么提供器就提供什么服务的规则来命名两者,但是你创建一个 火车serviceprovider, 然后再这个火车serviceprovider里绑定汽车类,那么火车serviceprovider提供的就是汽车对象,虽然用起来很尴尬,但你自己定义的你自己肯定会用的,别人估计是哭着用完的。
自定义的功能类所具有的功能如果需要规范点,那就先写个接口,比如Cache类,需要拥有get,set方法等,写个接口加以规范,以后用的时候也只需要调用实现了这个接口的类就行,不写接口也无所谓。
1、创建接口类,接口类的名字随便起,但是最好还是规范点,自己看着也舒服
创建 app\Contract\SktContract.php 接口类
namespace App\Contract;
interface SktContract
{
//展示队伍队员名单
public function list_team($team_name);
}
2、接下来按照这个接口来实现你的功能类
创建 app\Service\SktService.php
namespace App\Service;
use App\Contract\SktContract;
class SktService implements SktContract
{
public $name = null;
//展示队伍队员名单
public function list_team($team_name)
{
echo $team_name."的队员名单是Faker-bengi";
}
}
3、既然功能类写好了,那就要把他装在服务提供器中,到时候别人拿着你的服务提供器,就能获得实例化后的功能类对象了。
创建app\Providers\SktServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Service\SktService;
class SktServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* @return void
*/
public function register()
{
//使用singleton绑定单例
$this->app->singleton('skt',function(){
return new SktService();
});
//使用bind绑定接口
$this->app->bind('App\Contracts\SktContract',function(){
return new SktService();
});
}
}
这了绑定了两次,一次用singleton绑定的,一次用bind方法绑定的,区别是singleton绑定的是单例,继续往下看就知道区别了。
4、既然服务提供器也准备好了,那就把提供器加到框架的加载列表中,之后就可以在控制器中使用啦。
config/app.php在providers键名对应的数组中的最后,加入这行
App\Providers\SktServiceProvider::class,
5、接下来我们在控制器中使用我们刚刚自定义的服务
public function index()
{
$fooService1 = app()->make('App\Contracts\SktContract'); //这里产生的不是单例,这里用bind方法绑定的
$fooService2 = app()->make('App\Contracts\SktContract');
$fooService3 = app()->make('skt'); //这里产生的是单例,666,因为这里skt是用singleton绑定的
$fooService4 = app()->make('skt'); //这里产生的是单例,666
$fooService1->name='111';
$fooService2->name='222';
$fooService3->name='333';
$fooService4->name='444';
$fooService1->list_team('LOL-ssb'); //LOL-ssb的队员名单是Faker-bengi
var_dump($fooService1); //111
var_dump($fooService2); //222
var_dump($fooService3); //444
var_dump($fooService4); //444
}
通过app()->make('提供器中绑定时的键名');来获取功能类对象,用bing方法绑定的,获取出来的都是新对象,用singleton绑定的,获取的是单例。
6、那么问题来了,觉得这样调用还是很麻烦,能不能再简化调用?可以~ laravel有个facade功能。接下来我们创建一个文件:/vendor/laravel/framework/src/Illuminate/Support/Facades/Skt.php
namespace Illuminate\Support\Facades;
use Illuminate\Contracts\Console\Kernel as ConsoleKernelContract;
/**
* @method static bool list_team() //加上这行注释是为了让php_storm编辑器能够追踪函数
* Class Skt
* @package Illuminate\Support\Facades
*/
class Skt extends Facade //类名随便起,但是为了规范还是和功能类为主也叫Skt吧(功能类是叫SktService)
{
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor
{
return 'skt'; //这里一定要return一个绑定的键名,代表你接下来会获得那个键名绑定的对象
}
}
上面这个类主要是getFacadeAccessor方法返回的字符串要和你绑定时候的键名对应上,这里返回的是skt,之前在服务提供器中,不是有一句
$this->app->singleton('skt',function(){ //注意,这里的键名是skt
return new SktService();
});
吗,那么返回的就是这个return new SktService();对象。
7、好了,Facades文件也写完了,接下来我们回到控制器中,把调用功能类的代码直接改为以下代码
use Illuminate\Support\Facades\Skt; //这里要引入facades
class Test extends Controller
{
public function test()
{
Skt::list_team('LOL-ssb');
}
}
这里引入了 Illuminate\Support\Facades\Skt;获得了一个叫做Skt的类,但是不好意思,这个类和你的功能类SktService只是名字有点像,但是完全没有关系,起作用的是这个Skt类的getFacadeAccessor方法return了一个'skt'字符串,然后框架内部获取到这个'skt‘字符串之后,又根据这个'skt'字符串为键名,找到了之前通过singleton方法绑定的对象,那个对象才是真正的功能类。Skt::list_team()调用的实际上是SktService类的list_team()方法
总结:
接口类SktContract、功能类SktService、服务提供器SktServiceProvider(将功能类在里面绑定好)、将服务提供器加入到框架加载列表config/app.php、创建facades文件Skt(关键是renturn一个绑定时的键名)
实际上想要偷懒的话大可不必这么麻烦,创建一个SktService.php功能类,然后再框架原有的AppServiceProvider里面的register方法进行绑定也行,而且AppServiceProvider默认就在框架的加载列表中了,直接用就行,不过facades文件还是要自己创建。这样做的好处是省事,但是一旦各种各样的功能都在AppServiceProvider类中进行绑定的话,就会很乱,不符合单一功能原则,最好还是一个功能类就创建一个服务提供器。不过要想引入功能类大可不必这么麻烦呢,直接用trait,哪里想用就use进来就行了,省事。
Original url: Access
Created at: 2018-10-10 15:34:08
Category: default
Tags: none
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论