其實單例模式,說白了就是說一個類別只能實例化一次。但是我們要如何在這個實例化一次上面做文章呢。其實有個突破口就是__construct()這個魔術方法。這個方法就代表如果類別實例化的時候,就會自動執行這個方法。然後如果我把這個方法變成保護或私有的,會是什麼效果呢。
<?php class test{ protected function __construct(){ } } $test = new test(); ?>
然後執行下列,就會出現這個情況。
<img data-rawheight="125" data-rawwidth="994" src="https://img.php.cn/upload/article/000/054 /025/a79c550120d3e119df603c5755b0f293-0.jpg" class="origin_image zh-lightbox-thumb" width="994&科18628d34e0d3_r.jpg"> 這樣的話,就不能實例化了。這樣就保證不能隨便讓人給實例化了。
但是既然這樣的話,我們該怎麼實作實例化呢。就是這樣:
<?phpclass test{ protected function __construct(){ } public static function getInstance(){ $_test = new test(); return $_test; }}$test = test::getInstance();var_dump($test);?>
這樣的話。實例的話,就能出現了。讓我們來看看:
<img data-rawheight="50" data-rawwidth="152" src="https://img.php.cn/upload/article/000/ 054/025/a79c550120d3e119df603c5755b0f293-1.jpg" class="content_image" width="152">我說了這麼多,但我說到了這麼多重點。下面重點來了,只要我們再用一個關鍵字(static)就好了。鐺鐺鐺鐺:
<?php class test{ protected function __construct(){ } public static function getInstance(){ static $_test; if (empty($_test)) { $_test = new test(); } return $_test; } } $test1 = test::getInstance(); $test2 = test::getInstance(); $test3 = test::getInstance(); var_dump($test1,$test2,$test3); echo $test1 == $test2 ? 'true' : 'false'; echo "<br>"; echo $test2 == $test3 ? 'true' : 'false'; echo "<br>"; echo $test1 == $test3 ? 'true' : 'false'; ?>
看看結果:
<img data-rawheight="160" data-rawwidth= "133" src="https://img.php.cn/upload/article/000/054/025/a79c550120d3e119df603c5755b0f293-2.jpg" class=" gt;這樣的話就能實現php單例的效果了。
單例的話,最長用在需要只使用這一類,而不是會有多個類別。
打個比方。例如現在有個config類,這個類別主要是儲存這個專案的設定資訊。如果說這個類別能實例化多次的話,那麼如果在程式碼運行中對配置進行了修改,那麼你怎麼知道是在哪個配置類別中進行了修改了呢。這時候的話使用單例模式,就避免了情況的發生,所有對於設定檔的改變都是基於這個類別的實例進行修改的。而不會出現因為多個類別的實例化,操作對於操作的改變沒有即時的更新。而且,實例多個類別庫,佔用記憶體也會非常的厲害,這樣只會實例化一次。是不是好處多多。
其它見解:
把克隆也給私有化
class test{ private static $instance; private function __construct(){ } private function __clone(){ } public static function getInstance(){ if (! self::$instance instanceof self ) { self::$instance = new self(); } return self::$instance; } }
更直覺方法:
#點擊開啟連結
/* 单例设计模式 (单态) 定义: 一个类 只能允许有 一个对象存在. 1.不让进: 使类不能被实例化 2.留后门: 设置静态方法 3.给对象: 在静态方法里实例化该类 4.判初夜: 判断是否是 第一次产生该类的对象 5.设静态: 静态方法里 要使用静态属性 */ /*//1.不让进: 使类不能被实例化----------------- class Test { // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } }*/ /*//2.留后门: 设置静态方法-------------------- class Test { // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; } }*/ /*//3.给对象: 在静态方法里实例化该类------------------ class Test { // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; return new self();//实例化一个对象给你 } }*/ /*//4.判初夜: 判断是否是 第一次产生该类的对象------------------ class Test { private $obj = null;//属性值为对象,默认为null // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; if ($this->obj === null) { $this->obj = new self();//实例化一个对象 } //返回的属性 其实就是本对象 return $this->obj; } }*/ //5.设静态: 静态方法里 要使用静态属性------------------ class Test { private static $obj = null;//属性值为对象,默认为null // 设置 一个封装的构造方法 private function __construct() { //占位, 我就是不让你NEW我~~~ } //后门 public static function getObject() { echo "啊,我是后门,进吧!<br>"; if (self::$obj === null) { self::$obj = new self();//实例化一个对象 } //返回的属性 其实就是本对象 return self::$obj; } } /*Test::getObject();//使用静态方法访问该类里的方法 exit;*/ $t1 = Test::getObject(); $t2 = Test::getObject(); $t3 = Test::getObject(); $t4 = Test::getObject(); $t5 = Test::getObject(); $t6 = Test::getObject(); $t7 = Test::getObject(); $t8 = Test::getObject(); //判断 两个对象 是否是同一个对象 if ($t1 === $t6) { echo "哦, Yes! 是同一个实例<br>"; } else { echo "哦, No! 不是同一个实例<br>"; }
相關推薦:
以上是php單例模式詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!