PHP单例的几种实现方式
单例的定义
单例的几种实现方式
单例的应用场景
其他说明
附录
单例的定义
维基解释:
the singleton pattern is a design pattern that restricts the instantiation of a class to one object.
基于以上描述,结合多年软件开发经验,主要聚焦以下两点:
该类全局仅能有一个实例。本质上同全局变量,但又有所区别。
有统一的访问单例入口。
单例与全局变量的区别或者优缺点:
单例本质上与全局变量类似,全局可见、且贯穿整个程序的生命周期。除此之外,单例模式还拥有一些全局变量所有没有的特性:
延迟加载(lazy loading,或者叫懒汉模式),在使用到的时候才会创建。
同一个类型仅有一个实例。
根据维基给出的定义,要深入理解单例模式,需要弄明白以下几点:
保护限制在PHP实现中,体现在,(1)$instance变量是private且静态static,(2)构造函数、克隆函数均为private,即外边不能主动构造这个类的实例(instance)。
重用在软件开发过程中重用的方式一般有三种:组合、派生、模版。在本文实现中仅是对instance()函数的重用。通过继承Singleton类,instance()返回派生类的一个实例。
生命周期其实这里说是静态变量的生命周期。
2.单例的几种实现方式
特别说明:以下实现暂不考虑线程安全问题。
2.1 方式一:直接在类定义中做单例实现
<?php
class A
{
private static $instance = null; //static
private function __construct() {}//将构造函数设置为private,防止直接调用new A()构造.
private function __clone() {}//将clone()设置为private防止克隆
public static function getInstance()
{
if(!self::$instance instanceof self)
{
self::$instance = new self;
}
return self::$instance;
}
}
$a = A::getInstance();
$b = A::getInstance();
echo $a === $b ? “equal” : “not equal”;
?>
输出:
equal
2.2 方式二:将单例实现抽象成一个基类
<?php
abstract class Singleton
{
private static $_inst = array();
private function __construct() {}
private function __clone(){}
public static function instance() {
$class = get_called_class();
if(!array_key_exists($class, self::$_inst)
or is_null(self::$_inst[$class]))
{
self::$_inst[$class] = new static();
}
return self::$_inst[$class];
}
}
class B extends Singleton
{}
class C extends Singleton
{}
$b1 = B::instance();
$b2 = B::instance();
$c1 = C::instance();
echo “\n”;
echo ‘b1 vs b2 : ‘;
echo $b1 === $b2 ? “equal” : “not equal”;
echo “\n”;
echo ‘b1 vs c1 : ‘;
echo $b1 === $c1 ? “equal” : “not equal”;
?>
输出:
b1 vs b2 : equalb1 vs c1 : not equal
3. 单例的应用场景
由于PHP独特的运行模式,单例在实际开发过程中的场景相比于其他语言是有限的。
常见使用到单例的场景有:
数据库连接。在一个进程里只初始化一次DB连接, 极大降低了初始化过程中的各种资源。
在基类中实现单例,派生类通过继承方式同样拥有单例模式(如方式2)。
全局配置信息等,通过单例模式访问比直接使用全局变量看上去要优雅一点。
5. 附录
wikipediaSingleton pattern (https://en.wikipedia.org/wiki/Singleton_pattern)
Creating the Singleton design pattern in PHP5from stackoverflow (http://stackoverflow.com/questions/203336/creating-the-singleton-design-pattern-in-php5/203359#203359)