聊聊PHP中的單例模式與靜態變數

青灯夜游
發布: 2023-04-09 10:54:01
轉載
2728 人瀏覽過

聊聊PHP中的單例模式與靜態變數

在PHP中,沒有普遍意義上的靜態變數。與Java、C 不同,PHP中的靜態變數的存活週期只是每次PHP的會話週期,所以注定了不會有Java或C 那種靜態變數。

靜態變數在PHP中

在PHP中,靜態變數的存在意義只是在某個結構體中(方法或類)中傳遞一個變量,其作用域在此文件內。

function test(){
    static $var = 1; 
    echo $var++.'';
}
test();
test();
test();
//OutPut
//1
//2
//3
登入後複製

在函數test的三次呼叫中,變數$var在三次呼叫中都是存在的,並且每次會遞增1,而並沒有清空或重置
所以可以得出一個結論,靜態變數在目前結構體所在的生命週期中一直存在。在目前的例子中,test函數的生命週期就是目前PHP腳本,只要程式沒釋放都是有效的。

靜態變數在類別中

而在類別中,程式碼大概是這樣子的

class A
{
    private static $a = 1; 
    private $b = 2;
    public function add()
    {
        echo self::$a++.'';
        echo $this->b++.'';
    }
}
$class1 = new A();
$class1->add();
$class1->add();
$class2 = new A();
$class2->add();
$class2->add();
//Output
//1
//2
//2
//3
//3
//2
//4
//3
登入後複製

從上面的類別的運行結果來看,也得到了在函數中相同的結果

那麼大概總結一下就是

PHP的靜態變數在所在對應的結構體的生命週期中永久存在,且值保持一致,不論這個結構體被呼叫或實例化了多少次。

其實這就是動態變數和靜態變數的差別,具體看這篇文章。動態變數只在類別中有效,而靜態變數在目前php腳本。

靜態變數在單例模式中 

#再反過來看單例模式

class A
{
    private static $instance = null;
    private $b = 1;
    public static function get_instance()
    {
        if(self::$instance == null){
            $classname = __CLASS__;
            self::$instance = new $classname(); 
        }
        return self::$instance;
    }
    public function add()
    {
        $this->b++;
    }
    public function show()
    {
        echo $this->b;
    }
}
$a = A::get_instance();
$b = A::get_instance();
//此处$a和$b变量完全相同!
$a->add();
$a->show();
echo '';
$b->show();
//output
//2
//2
登入後複製

此時,由於單例模式存在,使得$a和$b完全是同一個對象,所以之間如果需要共享數據,完全不需要靜態變數(廢話,就是自己。因為在任何時候,應用程式中都只會有這個類別僅有的一個實例存在!無論你呼叫多少次單例,裡面的資料是不會被重新實例化的。)

所以,在單例模式中,靜態變數根本就沒有存在的意義。當然,如果你沒事幹,非要使用new方法初始化物件的話,也行,此時單例模式被打破,回歸到無單例模式的狀態。

如果為了防止使用new來實例化對象,那麼可以考慮對類別的__construct函數設定為private屬性

class A
{
    private static $instance = null;
    private $b = 1;
    private function __construct()
    {
    //Code in this function
    //could not be get out of the class
    }
    public static function get_instance()
    {
        if(self::$instance == null){
            $classname = __CLASS__;
            self::$instance = new $classname();
        }
        return self::$instance;
    }
    public function add()
    {
        $this->b++;
    }
    public function show()
    {
        echo $this->b;
    }
}
$a = A::get_instance();
$b = A::get_instance();
//此处$a和$b 变量完全相同!
$a->add();
$a->show();
echo '
';
$b->show();
//output
//2
//2
  
//如果尝试用new来实例化的话
$c = new A();
//output
//Fatal error: Call to private A::__construct() from invalid context in
//如果需要A类的实例化对象,只能通过开放的get_instance静态方法进行初始化
登入後複製

優點:單例模式可以避免大量的new操作,因為每一次new操作都會消耗記憶體資源和系統資源

缺點:在PHP中,所有的變數無論是全域變數或類別的靜態成員,都是頁面層級的,每次頁面執行時,都會重新建立新的對象,都會在頁面執行完畢後被清空,這樣似乎PHP單例模式就沒有什麼意義了,所以PHP單例模式我覺得只是針對單次頁面級請求時出現多個應用場景並需要共享同一物件資源時是非常有意義的

相關教學推薦:《PHP教學

以上是聊聊PHP中的單例模式與靜態變數的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:cnblogs.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!