单例模式(Singleton pattern)是一种创建型模式,它会限制应用程序,使其只能创建某一特定类类型的一个单一的实例。举个例子,一个Web站点将会需要一个数据库连接对象,但是应该有且仅有一个(把所有的数据库连接都放在这个连接上),我们可以使用单例模式来实现这种限制。
我们可以使用一个静态属性来保证对一个特定的类来说只存在一个的单一实例。
class SomeClass {
static private $_instance = NULL;
}
因为属性是静态的,它会类的所有实例共享。我们在属性中保存一个类的实例(也就是赋一个对象给它),然后所有对这个类的引用都可以使用这个属性。那么我们接下来创建一个方法,在类的实例不存在的时候,这个方法会创建一个类的实例,并且返回这个实例。
static function getInstance {
if (self::$_instance == NULL) {
self::$_instance = new SomeClass();
}
return self::$_instance;
}
通常情况下,在单例模式中这个方法的名字为getInstance()。
现在这个类可以这样使用:
$obj1 = SomeClass::getInstance();
$obj2 = SomeClass::getInstance();
$obj1和$obj2都指向了同一个实例。但是我们还是可以使用new或clone去创建这个类的一个新的对象,那么我们会得到多个实例,这就破坏了单例模式的限制。防止这种情况发生的一个技巧就是创建一个私有的构造函数,它不需要做任何事。
private function __construct() {}
private function __clone() {}
这样的话,我们就不能new一个对象实例了(因为构造函数私有),会报错:
Call to private Config::__construct() from invalid context,同样也不能clone了。
示例程序:
class Config {
static private $_instance = NULL;
private $_settings = array();
private function __construct() {}
static function getInstance() {
if (self::$_instance == NULL) {
self::$_instance = new Config();
}
return self::$_instance;
}
function set($index, $var) {
$this->_settings[$index] = $var;
}
function get($index) {
return $this->_settings[$index];
}
}
$CONFIG = Config::getInstance();
$CONFIG->set('live', 'true');
echo '$CONFIG["live"]: '.$CONFIG->get('live')."<br>";
$TEST = Config::getInstance();
echo '$TEST["live"]: '.$TEST->get('live');
运行结果: