简单示例
2022/03/12补充
-
特点
注册树模式通过将对象实例注册到一颗全局的对象树上, 需要的时候从对象树上采摘的模式设计方法 -
实现
<?php
class ClassA
{
public function methodA()
{
echo "class A";
}
}
class Register
{
protected static $objects = [];
public static function set($alias, $object)
{
self::$objects[$alias] = $object;
}
public static function get($alias)
{
return self::$objects[$alias];
}
public static function _unset($alias)
{
unset(self::$objects[$alias]);
}
}
Register::set('obj', new ClassA());
$obj = Register::get('obj');
$obj->methodA();
注册模式好处
1.解决全局共享和交换对象
2.已经创建好的对象,挂载到某个全局可以使用的数组上,在需要使用的时候,直接从该数组上获取即可
3.将对象注册到全局的树上去,任何地方直接访问
使用
注册模式使用
定义注册类Register.php
<?php
class Register
{
//定义容器
private static $objects;
//注册对象进入容器
public static function set($key, $obj)
{
//已经创建好的对象,挂载到某个全局可以使用的数组上,在需要使用的时候,直接从该诉数组上获取即可
if (isset(static::$objects[$key])){
throw new \Exception('该类已注册');
}
static::$objects[$key] = $obj;
return true;
}
//从容器中获取指定对象
public static function get($key)
{
if(!isset(static::$objects[$key])){
throw new \Exception('该类未注册');
}
return static::$objects[$key];
}
//删除容器中指定的对象
public static function unset_obj($key)
{
if(!isset(static::$objects[$key])){
throw new \Exception('该类未注册');
}
unset(static::$objects[$key]);
return true;
}
//获取容器中的所有对象
public static function all()
{
return static::$objects;
}
}
将引用的http请求类HttpClient.php服务,注册到容器中
<?php
/**
* @var HttpClient
*/
class HttpClient
{
/**
* @var 请求的路径
*/
private $url;
/**
* @var 请求方式
*/
private $method;
/**
* @var 请求参数
*/
private $param;
/**
* @var 请求头
*/
private $header;
/**
* @var 响应结果
*/
private $response;
/**
* @var 设置请求路径
*
* @param string url
*
* @return HttpClient
*/
private function setUrl(String $url = '')
{
$this->url = $url;
return $this;
}
/**
* @var 设置请求参数
*
* @param array param
*
* @return HttpClient
*/
private function setParam(array $param)
{
$this->param = http_build_query($param);
return $this;
}
/**
* @var 设置请求头部
*
* @param array header
*
* @return HttpClient
*/
private function setHeader(array $header)
{
foreach ($header as $key => $value) {
if (is_string($key)) {
$key = constant(strtoupper($key));
}
$this->header[$key] = $value;
}
return $this;
}
/**
* @var 设置请求方式
*
* @param string method
*
* @return HttpClient
*/
private function setMethod(String $method = 'GET')
{
$this->method = $method;
return $this;
}
/**
* @var 开始请求
*
* @return HttpClient
*/
private function exec()
{
$ch = curl_init();
if ($this->header) {
foreach ($this->header as $key => $value) {
curl_setopt($ch, $key, $value);
}
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $this->url);
if ($this->method == 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->param);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded; charset=utf-8',
'Content-Length: ' . strlen($this->param)
));
} elseif ($this->method == 'GET') {
curl_setopt($ch, CURLOPT_URL, $this->url.'?'.$this->param);
curl_setopt($ch, CURLOPT_HEADER, false);
}
$info = curl_getinfo($ch);
$data = curl_exec($ch);
$error = curl_errno($ch);
curl_close($ch);
$this->response = [
'code' => $error ? 1 : 0,
'message' => $error,
'info' => $info,
'data' => $data,
];
return $this;
}
/**
* @var 获取响应数据
*
* @throw Exception
*
* @return array|string
*/
public function getBody()
{
if (!$this->response) {
throw new Exception('no httpRequest');
}
return $this->response['data'];
}
/**
* @var 获取响应状态码
*
* @throw Exception
*
* @return int
*/
public function getCode()
{
if (!$this->response) {
throw new Exception('no httpRequest');
}
return $this->response['code'];
}
/**
* @var 获取错误信息
*
* @throw Exception
*
* @return int|array
*/
public function getMessage()
{
if (!$this->response) {
throw new Exception('no httpRequest');
}
return $this->response['message'];
}
/**
* @var 获取响应信息
*
* @return array
*/
public function getInfo()
{
if (!$this->response) {
throw new Exception('no httpRequest');
}
return $this->response['info'];
}
/**
* @var GET请求
*
* @param string url
* @param array param
* @param array header
*
* @return HttpClient
*/
public function get(String $url, array $param = [], array $header = [])
{
return $this->setMethod('GET')->setUrl($url)->setParam($param)->setHeader($header)->exec();
}
/**
* @var POST请求
*
* @param string url
* @param array param
* @param array header
*
* @return HttpClient
*/
public function post(String $url, array $param = [], $header = [])
{
return $this->setMethod('POST')->setUrl($url)->setParam($param)->setHeader($header)->exec();
}
/**
* @var 清理垃圾
*/
public function __destruct()
{
$this->url = null;
$this->method = null;
$this->param = null;
$this->header = null;
$this->response = null;
}
}
抽象工厂类
<?php
//require 'D:\phpstudy_pro\WWW\project\HttpClient.php';
//接口中每个方法都只有声明而没有实现
//接口需要实现,用implements
//接口中只能声明public的方法,不能声明private和protected的方法,不能对方法进行实现,也不能声明实例变量;但是抽象类中可以
interface AbstractFactory
{
public function get(String $url, Array $param = [], Array $header = []) : HttpClient;
public function post(String $url, Array $param = [], Array $header = []) : HttpClient;
}
//Requst 实现AbstractFactory接口
class Requst implements AbstractFactory
{
protected $httpclient;
public function __construct()
{
$this->httpclient = new HttpClient;
}
public function __destruct()
{
$this->httpclient = null;
}
public function get(String $url, Array $param = [], Array $header = []) : HttpClient
{
return $this->httpclient->get($url, $param, $header);
}
public function post(String $url, Array $param = [], Array $header = []) : HttpClient
{
return $this->httpclient->post($url, $param, $header);
}
}
class MyVue extends Requst
{
public function home()
{
return $this->get('https://fanyi.baidu.com/translate?aldtype=16047&query=&keyfrom=baidu&smartresult=dict&lang=auto2zh#en/zh/response')->getBody();
}
}
class GitHub extends Requst
{
public function apiList()
{
return $this->get('https://api.github.com/', [], [
'CURLOPT_USERAGENT' => 'http://developer.github.com/v3/'
])->getBody();
}
}
注册模式的使用
<?php
require 'D:\phpstudy_pro\WWW\project\HttpClient.php';
//include './factory/Ease.php';
//include './factory/Method.php';
include './factory/AbstractFactory.php';
include './Register.php';
//Register::set('ease', new Ease);
//Register::set('get', new Get);
Register::set('requst', new Requst);
Register::set('myVue', new MyVue);
Register::set('github', new GitHub);
//从容器中获取注册的github对象服务
$arr = Register::get('github')->apiList();
echo "<pre>";
print_r(json_decode($arr,true));
echo "</pre>";
thinkphp6使用
说明
服务:比如发送邮件的服务类,发起http请求时的curl服务类等
系统服务的概念是指在执行框架的某些组件或者功能的时候需要依赖的一些基础服务,服务类通常可以继承系统的think\Service类,但并不强制(如果继承think\Service的话可以直接调用this->app获取应用实例)。
你可以在系统服务中注册一个对象到容器,或者对某些对象进行相关的依赖注入。由于系统服务的执行优先级问题,可以确保相关组件在执行的时候已经完成相关依赖注入。
容器:服务实例的管理者
容器类的工作由think\Container类完成,但大多数情况我们只需要通过app助手函数或者think\App类即可容器操作,如果在服务类中可以直接调用this->app进行容器操作。
依赖注入其实本质上是指对类的依赖通过构造器完成自动注入,例如在控制器架构方法和操作方法中一旦对参数进行对象类型约束则会自动触发依赖注入,由于访问控制器的参数都来自于URL请求,普通变量就是通过参数绑定自动获取,对象变量则是通过依赖注入生成。
使用
1、你可以通过命令行生成一个服务类,例如:
php think make:service FileSystemService
2、服务注册到容器
定义好系统服务后,你还需要注册服务到你的应用实例中。
可以在应用的全局公共文件service.php中定义需要注册的系统服务,系统会自动完成注册以及启动。例如:
3、注册服务使用
register方法通常用于注册系统服务,也就是将服务绑定到容器中,例如:绑定curl类
4、在控制器中使用
$this->curl = app('curl');
$this->curl->test();