首頁  >  文章  >  後端開發  >  php單例模式詳解

php單例模式詳解

小云云
小云云原創
2018-03-21 11:45:151608瀏覽

其實單例模式,說白了就是說一個類別只能實例化一次。但是我們要如何在這個實例化一次上面做文章呢。其實有個突破口就是__construct()這個魔術方法。這個方法就代表如果類別實例化的時候,就會自動執行這個方法。然後如果我把這個方法變成保護或私有的,會是什麼效果呢。


<?php
class test{

	protected function __construct(){

	}
}

$test = new test();
?>

然後執行下列,就會出現這個情況。

&lt;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"&gt; 這樣的話,就不能實例化了。這樣就保證不能隨便讓人給實例化了。
但是既然這樣的話,我們該怎麼實作實例化呢。就是這樣:


<?phpclass test{

	protected function __construct(){

	}

	public static function getInstance(){
		$_test = new test();
		return $_test;
	}}$test = test::getInstance();var_dump($test);?>

這樣的話。實例的話,就能出現了。讓我們來看看:
&lt;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"&gt;我說了這麼多,但我說到了這麼多重點。下面重點來了,只要我們再用一個關鍵字(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 ? &#39;true&#39; : &#39;false&#39;;
echo "<br>";
echo $test2 == $test3 ? &#39;true&#39; : &#39;false&#39;;
echo "<br>";
echo $test1 == $test3 ? &#39;true&#39; : &#39;false&#39;;
?>

看看結果:
&lt;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單例模式demo詳解

PHP單例模式的簡單用法分享

以上是php單例模式詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn