php单例模式

2019-08-28 09:23:15

什么是单例模式#

单例模式,是一种常见的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。

单例模式的优点#

  • 减少频繁创建,节省了cpu。

  • 静态对象公用,节省了内存。

  • 功能解耦,代码已维护。

单例模式的应用#

实际项目中像数据库查询,日志输出,全局回调,统一校验等模块。这些模块功能单一,但是需要多次访问,如果能够全局唯一,多次复用会大大提升性能。这也是单例存在的必要性。

如何设计单例模式#

通过上面的描述,单例的核心是,实例一次生成,全局唯一,多次调用。因此在单例模式必须包含三要素。

  1. 私有化构造函数,私有化clone。也就是不能new,不能clone【唯一】

  2. 拥有一个静态变量,用于保存当前的类。【唯一如何保存】

  3. 提供一个公共的访问入口。【可以访问】

PHP实现#

复制代码

class Singleton
{    // 私有化构造方法
    private function __construct()
    {

    }    
    // 私有化clone方法
    private function __clone()
    {
    
    }    // 保存实例的静态对象
    public static $singleInstance;    /**
     * 声明静态调用方法
     * 目的:保证该方法的调用全局唯一
     *
     * @return  Singleton     */
    public static function getInstance()
    {        if (!self::$singleInstance) {
            self::$singleInstance = new self();
        }        return self::$singleInstance;
    }    // 调用单例的方法
    public function singletonFunc()
    {        echo "call single ton method";
    }

}$singleInstance =  Singleton::getInstance();$singleInstance->singletonFunc();$singleInstance2 =  Singleton::getInstance();$singleInstance2->singletonFunc();// 校验是否是一个实例var_dump($singleInstance === $singleInstance2);  // true ,一个对象

复制代码

php中static属性和方法的继承问题(补充知识)#

复制代码

class Base
{    public static $var = 'var';    public static function testStaticFun()
    {        echo 'func';
    }
}class A extends Base
{    public function testSelf()
    {        echo self::$var;
    }    public function testParent()
    {        echo parent::$var;
    }    public function setSelf()
    {
        self::$var = 'self';
    }    public function setParent()
    {
        parent::$var = 'parent';
    }    public static function testStaticFun()
    {
        parent::testStaticFun();        echo 'over';
    }
}$objA = new A();     
  
$objA->testSelf();    // var$objA->testParent();  // var$objA->setSelf();$objA->testSelf();    // self$objA->testParent();  // selfecho Base::$var;      // self$objA->setParent();$objA->testSelf();    // parent$objA->testParent();  // parentecho Base::$var;      // parentBase::testStaticFun();    // funcA::testStaticFun();       // func over

复制代码

 

  1. 静态成员可以使用 访问控制关键字修饰,可以被继承和重写
    也就就说子类可以继承到父类的静态变量、方法…遵循“关键字”规则

  2. 如果子类没有重写,那么子类调用的实际是父类的静态方法
    这个也很简单明了,继承的基本规则,没什么好解释的

  3. 静态成员持有者是类不是对象,所以类的多个实例共享同一个静态属性的,在一个实例中修改静态属性会影响到另一个实例中的静态属性。
    这个就是重点了,好好理解下,单列模式也是利用这个特性。

所以代码中 self::$var 和 parent::$var 其实指向的都是父类中的$var
最后举个栗子:
单例模式下,$var你可以理解为数据库连接,父类生成一个连接后,继承的子类直接使用这个连接即可连接使用数据库。
但是如果子类自己生成一个连接$var,那么使用的时候就要区分是self::$var还是parent::$var,因为俩个值可能不一样,连接的数据库也不一样,万一是主从呢。


  • 2017-02-13 17:50:05

    cURL error 60: SSL certificate problem: unable to get local issuer certificate

    Drupal 8 version uses Guzzle Http Client internally, but under the hood it may use cURL or PHP internals. If you installed PHP cURL on your PHP server it typically uses cURL and you may see an exception with error Peer certificate cannot be authenticated with known CA certificates or error code CURLE_SSL_CACERT (60).

  • 2017-02-16 08:09:01

    HTML中PRE和p的区别

    pre 元素可定义预格式化的文本。被包围在 pre 元素中的文本通常会保留空格和换行符。而文本也会呈现为等宽字体。 <pre> 标签的一个常见应用就是用来表示计算机的源代码。

  • 2017-02-16 15:14:14

    动态加载js和css

    开发过程中经常需要动态加载js和css,今天特意总结了一下常用的方法。