<?php /** * 【单例模式】 * 总结:防止外部new对象;防止子类继承;防止克隆。 */ header("Content-type: text/html; charset=utf-8"); /******* NO.1 普通的可以调用的类 ******/ //先定义一个类,实例化两次,看看是否全等(===) class sigleA{ } $sa1 = new sigleA(); $sa2 = new sigleA(); //注意:当两个对象是一个的时候,才会全等 //此处输出 “sa-不是一个对象” if($sa1 === $sa2){ echo 'sa-是一个对象<br>'; }else{ echo 'sa-不是一个对象<br>'; } /********************* NO.2 封锁new操作 ********************/ //getIns 预先判断实例 class sigleB{ protected static $ins = null; public static function getIns(){ //getIns 获取实例 if(self::$ins === null){ //把【自身对象】 赋给 一个自己的 【静态属性】 self::$ins = new self(); } return self::$ins; } //保护的 构造函数 protected function __construct(){ } } //再去判断两个对象 $sb1 = sigleB::getIns(); $sb2 = sigleB::getIns(); //此处输出 “sb-是一个对象” if($sb1 === $sb2){ echo 'sb-是一个对象<br>'; }else{ echo 'sb-不是一个对象<br>'; } ////----- 但是,下面用一个新的类继承自上面的 sigleB ... class multi extends sigleB{ public function __construct(){ } } $m1 = new multi(); $m2 = new multi(); //此处输出 “m-不是一个对象”,原因在于被继承后,__construct 被公开了 if($m1 === $m2){ echo 'm-是一个对象<br>'; }else{ echo 'm-不是一个对象<br>'; } /********************* NO.3 final防止继承 ********************/ class sigleC{ protected static $ins = null; public static function getIns(){ if(self::$ins === null){ self::$ins = new self(); } return self::$ins; } //若方法前加上final,则方法不能被覆盖; //若类前加上final,则类不能被继承 final protected function __construct(){ } //同样的,防止克隆(clone) final protected function __clone(){ } } $sc1 = sigleC::getIns(); $sc2 = clone $sc1; //被克隆了,又产生了多个对象; //如果没加上 防止克隆的代码,此处输出 “sc-不是一个对象” //上面加上了 final protected function __clone(),这里就会出错: //Fatal error: Call to protected sigleC::__clone() from context '' in ... if($sc1 === $sc2){ echo 'sc-是一个对象<br>'; }else{ echo 'sc-不是一个对象<br>'; }