实现单例模式,禁止多次实例化

作者: admin 分类: php基础入门 发布时间: 2025-03-02 22:53

php中类实现单例模式,即在同一个php进程里面,每个类如何实现仅初始化一次。

技术点一:被实例化的方式

因为目标是在php进程中,禁止类的多次实例化。那么,就需要知道类被实例化的方式。

  • 最正统的就是__construct()方法,通过new class()进行初始化。
  • 非正统的克隆__clone()方法,通过clone $obj来进行初始化。

所以,为了阻止代码意外的通过传统方式初始化成功。需要改写这两个默认方法属性为private,并不是说非要置空方法体内容。只是改成private后,就无法在类外部被意外初始化,会直接报错。例如:

// $aaa = new Sunan();                 
// Fatal error: Call to private Sunan::__construct() from invalid context
// $bbb = clone Sunan::getInstance();  
// Fatal error: Call to private Sunan::__clone() from context
参考文章:

对于类初始化来说,new self()也是可以初始化的。

技术点二:判断当前类的方法

既然禁用了__construct()方法,就必须自定义初始化的方法了。这里就可能需要用到__CLASS__get_class()来获得当前类名,以便进行初始化。

这里需要说明的是:__CLASS__get_class()这两种途径,返回的类名是代码在哪个类里面,就返回哪个类的名字,不考虑继承关系的。

参考文章:

技术点三:static静态变量

静态变量实际上是实现单例模式的关键因素之一,本文中的这几个方案里面,静态变量区别就是存在的位置,或者说作用域的区别。它的特点就是一旦被初始化,就跳出初始化的代码逻辑了,进而升级为一个类似全局变量的特殊存在。

如果要对静态变量的用法,有更多的了解,可以参考:

方案一,类的静态属性

class Sunan{
    private function __construct(){}
    private function __clone(){}
    static $instance = null;
    public static function getInstance(){
        if (self::$instance == null) {
            // self::$instance = new Sunan();
            $s = __CLASS__;
            self::$instance = new $s;
        }
        return self::$instance;
    }
    public function sayHi(){
        echo "hi,苏南大叔";
    }
}
Sunan::getInstance()->sayHi();

方案二,类静态属性+self

class Sunan2{
    private function __construct(){}
    private function __clone(){}
    private static $instance;
    public static function getInstance(){
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    public function sayHi(){
        return "hi,苏南大叔";
    }
}
echo Sunan2::getInstance()->sayHi();

方案三,函数里的静态变量

class Sunan3{
    private function __construct(){}
    private function __clone(){}
    public static function getInstance(){
        static $instance;
        if (!isset($instance)) {
            $c = __CLASS__;
            $instance = new $c;
        }
        return $instance;
    }
    public function sayHi(){
        return "hi,苏南大叔";
    }
}
echo Sunan3::getInstance()->sayHi();
fb041a361ebcf78c

方案四,总体管控(工厂模式)

class singleton {
    public static function getInstance($class){
        static $instances = array();
        if (!array_key_exists($class, $instances)) {
            $instances[$class] = new $class;
        }
        $target = $instances[$class];
        return $target;
    }
}
class Sunan9{
    public function sayHi() {
        echo "hi,苏南大叔";
    }
}
singleton::getInstance('Sunan9')->sayHi();
这个方案里面,并没有修改__construct()__clone()为私有,大家想想看,是为啥呢?
98e2cdf44d1547fb

相关文章

 

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

标签云