php怎么实现单例模式
实现单例模式的基本原理
单例模式确保一个类只有一个实例,并提供一个全局访问点。在PHP中,可以通过以下方式实现:
- 私有化构造函数,防止外部直接实例化
- 私有化克隆方法,防止通过克隆创建新实例
- 静态属性保存唯一实例
- 静态方法提供全局访问点
基础实现代码示例
class Singleton {
private static $instance;
private function __construct() {
// 私有构造函数防止外部实例化
}
private function __clone() {
// 私有克隆方法防止克隆实例
}
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
线程安全考虑
PHP作为脚本语言通常运行在单线程环境下,不需要像Java那样考虑复杂的线程安全问题。但在某些特殊情况下(如使用pthreads扩展),可以增加同步锁:
class ThreadSafeSingleton {
private static $instance;
private static $lock = false;
private function __construct() {}
public static function getInstance() {
if (!isset(self::$instance)) {
while(self::$lock) {
usleep(100);
}
self::$lock = true;
self::$instance = new self();
self::$lock = false;
}
return self::$instance;
}
}
继承问题处理
如果需要允许单例类被继承,可以将构造函数设为protected而非private:
class BaseSingleton {
protected static $instance;
protected function __construct() {}
protected function __clone() {}
public static function getInstance() {
if (!isset(static::$instance)) {
static::$instance = new static();
}
return static::$instance;
}
}
class ChildSingleton extends BaseSingleton {
protected function __construct() {
parent::__construct();
}
}
序列化问题处理
为防止通过序列化和反序列化创建多个实例,需要实现__wakeup方法:
class SerializableSingleton {
private static $instance;
private function __construct() {}
public function __wakeup() {
throw new Exception("Cannot unserialize singleton");
}
public static function getInstance() {
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}
实际应用示例
数据库连接是单例模式的典型应用场景:
class Database {
private static $instance;
private $connection;
private function __construct() {
$this->connection = new PDO(
'mysql:host=localhost;dbname=test',
'username',
'password'
);
}
public static function getInstance() {
if (!self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
public function getConnection() {
return $this->connection;
}
}
// 使用方式
$db = Database::getInstance()->getConnection();






