什么是系统服务?系统服务是对于程序要用到的类在使用前先进行类的标识的绑定,以便容器能够对其进行解析(通过服务类的 register
方法),还有就是初始化一些参数、注册路由等(不限于这些操作,主要是看一个类在使用之前的需要,进行一些配置,使用的是服务类的 boot
方法)。以下面要介绍到的 ModelService
为例,ModelService
类提供服务,ModelService
类主要对 Model
类的一些成员变量进行初始化(在 boot
方法中),为后面 Model
类的「出场」布置好「舞台」。
自定义系统服务
接着,我们自己动手来写一个简单的系统服务。
定义被服务的对象(类)
创建一个文件:app\common\MyServiceDemo.php
,写入代码如下:
<?php
namespace app\common;
class MyServiceDemo
{
// 注意:类里面没有成员属性,否则一律都必须new
// 类里面只有方法,所以他可以放到容器中
// 因为有成员属性,必须单独new 出来才行
// 好处: 单例模式,只需要new 一次, 方便使用, 节约资源,提高利用率,防止对象重复实例化
//定义一个静态成员变量
// protected static $myStaticVar = '123';
// 设置该变量的值
public static function setVar($value)
{
// self::$myStaticVar = $value;
return $value;
}
//用于显示该变量
public function showVar($value)
{
return $value;
}
}
定义服务提供者
在项目根目录,命令行执行 php think make:service MyService
,将会生成一个 app\service\MyService.php
文件,
执行代码:
php think make:service MyService
在其中写入代码:
<?php
declare (strict_types = 1);
namespace app\service;
use app\common\MyServiceDemo; //要use一下
class MyService extends \think\Service
{
/**
* 注册服务
*系统服务注册的时候,执行register方法
* @return mixed
*/
public function register()
{
// 将绑定标识到对应的类
$this->app->bind('my_service', MyServiceDemo::class);
}
/**
* 执行服务
*系统服务注册之后,执行boot方法
* @return mixed
*/
public function boot()
{
// 将被服务类的一个静态成员设置为另一个值
MyServiceDemo::setVar('关注我');
}
}
配置系统服务
在 app\service.php
文件(如果没有该文件则创建之),写入:
<?php
use app\AppService;
// 系统服务定义文件
// 服务在完成全局初始化之后执行
return [
AppService::class,
\app\service\MyService::class
];
在控制器中调用
<?php
declare (strict_types = 1);
namespace app\index\controller;
use app\BaseController;
use think\response\Json;
use app\common\MyServiceDemo;
class Index extends BaseController
{
public function index(MyServiceDemo $MyServiceDemo)
{
// //依赖注入调用
$MyServiceDemo->showVar();
// //容器标识调用
// 因为在服务提供类的register方法已经绑定了类标识到被服务类的映射
// 所以这里可以使用容器类的实例来访问该标识,从而获取被服务类的实例
// 这里也输出‘456’
$data = $this->app->my_service->showVar();
// 以下是为了比较有没有成员属性的区别
// $data1 = $this->app->my_service->showVar('abc');
// if ($data === $data1) {
// echo $data;
// }else{
// echo 2;
// }
}
}
总结
使用系统服务有大大的好处和避免了直接修改类的坏处。从以上分析来看,个人觉得,使用系统服务,可以对一个类进行非入侵式的「配置」,如果哪天一个类的某些设定需要修改,我们不用直接修改这个类,只需要修改服务提供类就好了。对于扩展包来说,系统服务使其可以在扩展中灵活配置程序,达到开箱即用的效果。不过,有个缺点是系统服务类都要在程序初始化是进行实例化,如果一个系统的服务类很多,势必影响程序的性能。