单例模式:
单例模式顾名思义,就是只有一个实例。作为对象的创建模式, 单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
为什么要使用PHP单例模式:
php的应用主要在于数据库应用, 一个应用中会存在大量的数据库操作, 在使用面向对象的方式开发时, 如果使用单例模式, 则可以避免大量的new 操作消耗的资源,还可以减少数据库连接这样就不容易出现 too many connections情况。
/**
* 设计模式之单例模式
* $instance必须声明为静态的私有变量
* 构造函数必须声明为私有,防止外部程序new类从而失去单例模式的意义
* getInstance()方法必须设置为公有的,必须调用此方法以返回实例的一个引用
* ::操作符只能访问静态变量和静态函数
* new对象都会消耗内存
* 使用场景:最常用的地方是数据库连接。
* 使用单例模式生成一个对象后,该对象可以被其它众多对象所使用。
*/
class simple{
private static $instance;
private function __construct(){
echo "我实例了";
}
public static function getInstance(){
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __clone(){}
}
$obj = simple::getInstance();
$obj1 = simple::getInstance();
$obj2 = simple::getInstance();
$obj3 = simple::getInstance();
var_dump([$obj,$obj1,$obj2,$obj3]);
然后我们运行一下上面的文件
运行了四次这个类,但构造函数中的文字,只出现了一次,说明没有从新实例化该对象,在一个线程中,这个类只能被实例化一次。
下面实现一个redis的单例模式:
class redisSimple{
private static $instance;
private function __construct(){
self::$instance = new \Redis();
$config = C("REDIS"); // redis配置信息;我这里是tp的
self::$instance->connect($config['host'],$config['port']);
if(isset($config['password'])){
self::$instance->auth($config['password']);
}
}
public static function getInstance(){
if (!self::$instance) {
self::$instance = new self;
}
return self::$instance;
}
private function __clone(){}
}
redisSimple::getInstance();
再实现一个在大多数框架之中,单例模式的用法,常见于使用在数据库场景
class DB{
private static $db;
private static $instance;
private function __construct(...)
{
self::$db = pg_connect(...);//postgrsql
}
private function __clone() {}; //覆盖__clone()方法,禁止克隆
public static function getInstance()
{
if(! (self::$instance instanceof self) ) {
self::$instance = new self();
}
return self::$instance;
}
public function addUserInfo(...)
{
//新增操作
}
public function getUserInfo(...)
{
//获取操作
}
}
$db = DB::getInstance();
$db->addUserInfo(...);
$db->getUserInfo(...);