单例模式

//注:单例模式常用也常考,请认真练习

单例模式:

主要思路

1.保护或私有构造函数,防止外部实例化
2.内部开放一个公共的静态方法,负责实例化
3.类有一个静态属性存放对象

当静态属性已经存放对象,直接return 该对象。

第一步:一个普通的类
这个普通类,可以new来实例化
这显然不是单例

class single{


}

$s1=new single();
$s2=new single();
$s3=new single();


 

第二步:看来new是罪恶之源,干脆不让new了

我们把构造方法 保护/私有
外部不能new了            new了报错了
----但引入一个问题,不能new,那得不到对象,这不是单例,这是0例模式。

class single{
   protected function __construct(){
  
   }
}

$s1=new single();

第三步,通过内部的static方法,来调用


class single{

 public $hash;   //证明

  protected function __construct(){
        $this->hash=mt_rand(1,99999);  //随机码   证明
  }

  static public function getInstance(){
        return new self();        //self 代表本类  也可以直接写上类名
  }


}


$s1=single::getInstance();
$s2=single::getInstance();

两个对象什么时间相等?

答:只有指向一个对象地址的时候,才相等。


证明给你看!

 打了证明的都是可以证明不是一个对象的

print_r($s1);  //证明
print_r($s2);  //证明

if($s1==$s2){             //证明
    echo '是一个对象';      //证明
}else{
   echo '不是一个对象';       //证明 
}

//输出    不是一个对象


 

第四步,通过内部的static方法实例化,
并且,把实例保存在内部的静态属性上


简单的单例模式完成

class single{

 public $hash;  

 static protected $ins=NULL;

  protected function __construct(){
        $this->hash=mt_rand(1,99999);
  }

  static public function getInstance(){
     
        if(self::$ins instanceof self){  //instanceof 专门判断某个对象是不是某个类的实例用的

       return self::$ins;
  }

  self::$ins=new self();
  return self::$ins;

  }


}


$s1=single::getInstance();
$s2=single::getInstance();

print_r($s1); 
print_r($s2); 


if($s1==$s2){            
    echo '是一个对象';    
}else{
   echo '不是一个对象';      
}


//输出    是一个对象

//-----------------看问题------------------------//


class test extends single{
  
    public function __construct(){
      parent::__construct();
 }
 
}


$t1=new test();               //假如 你改成    $t1=test::getInstance();  那就没问题了
$t2=new test();

print_r($t1); 
print_r($t2); 


if($t1==$t2){            
    echo '是一个对象';    
}else{
   echo '不是一个对象';      
}


//输出    不是一个对象


//问题1:我们辛苦写的单例,继承一下就不灵了

//解决  final    可以解决


class s{

 public $hash;  

  static protected $ins=NULL;

   final protected function __construct(){
        $this->hash=mt_rand(1,99999);
  }

  static public function getInstance(){
     
        if(self::$ins instanceof self){  //instanceof 专门判断某个对象是不是某个类的实例用的

       return self::$ins;
  }

  self::$ins=new self();
  return self::$ins;

  }


}


class t extends s{
   
}

$t1=t::getInstance();
$t2=t::getInstance();

print_r($t1);
print_r($t2);


$t3=clone $t2;        //这里是克隆一份给$t3

if($t1===$t2){            
    echo '是一个对象';         // 输出 是一个对象
}else{
   echo '不是一个对象';      
}


echo "
";


if($t3===$t2){       //用全等于  暴露出不是一个对象      
    echo '是一个对象';     
}else{
   echo '不是一个对象';     //  输出 不是一个对象 
}


t1 t2显然是一个对象
而clone出来的t3显然是另一个对象



//clone又多出一个对象,试问,如何解决?

//提示:请看魔术方法  clone


//魔术方法很多

  __construct

  __destruct

  __clone

  __callstatic

    等等

原文地址:https://www.cnblogs.com/suiyuewuxin/p/5608485.html