补充2022/03/12
- 特点
三私一公: 私有静态属性, 私有构造方法, 私有__clone()方法, 公有静态方法
-实现
Class Test
{
private static $_instace;
private function __construct() {
}
private function __clone() {
}
public function test() {
echo "test";
}
public static function getInstace()
{
if (self::$_instace == null) {
self::$_instace = new Test();
}
return self::$_instace;
}
}
$obj = Test::getInstace();
$obj->test();
单例模式
单例模式已经被考虑列入到反模式中!请使用依赖注入获得更好的代码可测试性和可控性!
单例模式通常情况下是内部实例化。
目标
使应用中只存在一个对象的实例,并且使这个单实例负责所有对该对象的调用。
例子
1、数据库连接器
2、日志记录器
3、应用锁文件 (理论上整个应用只有一个锁文件 …)
UML 图
代码
标准单例模式: HttpClient.php
1.创建一个静态私有变量存放实例化的对象
2.创建一个私有构造函数
3.防止外部克隆该类
4.防止序列化
5.提供唯一的静态入口(判断$instance变量是否是HttpClient类的实例,如果不是,则实例化本身,如果是则直接返回)
<?php
/**
* @var HttpClient
*/
class HttpClient
{
/**
* @var 请求的路径
*/
private $url;
/**
* @var 请求方式
*/
private $method;
/**
* @var 请求参数
*/
private $param;
/**
* @var 请求头
*/
private $header;
/**
* @var 响应结果
*/
private $response;
//1.创建一个静态私有变量存放实例化的对象
private static $instance;
//2.创建一个私有构造函数
private function __construct()
{
}
//3.防止外部克隆该类
private function __clone()
{
}
//4.防止序列化
private function __wakeup()
{
}
//5.提供唯一的静态入口
public static function getInstance()
{
//判断$instance变量是否是HttpClient类的实例,如果不是,则实例化本身,如果是则直接返回
//instanceof 用于确定一个 PHP 变量是否属于某一类 class 的实例
if(!(static::$instance instanceof static )){ //static 换成self也可以,只不过static比self更精准些
static::$instance = new static;
}
return static::$instance;
}
/**
* @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 './inside/HttpClient.php';
$obj1 = HttpClient::getInstance();
$obj2 = HttpClient::getInstance();
var_dump($obj1 === $obj2);
显示结果
外部调用单例模式:也就是代理模式(TP5.1facade)
单例类:
1.防止外部克隆该类
2.防止序列化
代理类:
1.引用单例类,在代理类中实例化单例类
2.通过静态调用代理类从而使用单例类
单例类
<?php
/**
* @var HttpClient
*/
class HttpClient
{
/**
* @var 请求的路径
*/
private $url;
/**
* @var 请求方式
*/
private $method;
/**
* @var 请求参数
*/
private $param;
/**
* @var 请求头
*/
private $header;
/**
* @var 响应结果
*/
private $response;
//1.防止外部克隆该类
private function __clone()
{
}
//2.防止序列化
private function __wakeup()
{
}
/**
* @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
include 'D:\phpstudy_pro\WWW\project\singleton\outside\HttpClient.php';
class Singleton
{
private static $httpclicent;
public static function httpclient()
{
if (!(static::$httpclicent instanceof static)){
static::$httpclicent = new static;
}
return static::$httpclicent;
}
}
使用
require './outside/Singleton.php';
$obj1 = Singleton::httpclient();
$obj2 = Singleton::httpclient();
var_dump($obj1 === $obj2);
结果页面
参考文档:
https://designpatternsphp.readthedocs.io/zh_CN/latest/Creational/Singleton/README.html