單例模式與靜態變數在PHP中

來源:互聯網
上載者:User

標籤:cti   html   迴歸   區別   style   htm   add   ==   public   

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

所以,在PHP中,靜態變數的存在意義僅僅是在某個結構體中(方法或者類)中傳遞一個變數,其範圍在此檔案內。
看個例子好了

 

 1 function test(){ 2     static $var = 1;  3     echo $var++.‘ 4 ‘; 5 } 6 test(); 7 test(); 8 test(); 9 //OutPut10 //111 //212 //3

在函數test的三次調用中,變數$var在三次調用中都是存在的,並且每次會遞增1,而並沒有清空或者重設
所以可以得出一個結論,靜態變數在當前結構體所在的生命週期中一直存在。當前的例子中,test函數的生命週期就是當前PHP指令碼,只要程式沒釋放都是有效。
而在類中,代碼大概是這樣子的

 

 1 class A 2 { 3     private static $a = 1;  4     private $b = 2; 5     public function add() 6     { 7         echo self::$a++.‘ 8 ‘; 9         echo $this->b++.‘10 ‘;11     }12 }13 $class1 = new A();14 $class1->add();15 $class1->add();16 $class2 = new A();17 $class2->add();18 $class2->add();19 //Output20 //121 //222 //223 //324 //325 //226 //427 //3

 

從上面的類的運行結果來看,也得到了在函數中相同的結果
那麼大概總結一下就是
PHP的靜態變數在所在對應的結構體的生命週期中永久存在,並且值保持一致,不論這個結構體被調用或者執行個體化了多少次。

其實這就是動態變數和靜態變數的區別,具體看此篇文章。動態變數只在類中有效,而靜態變數在當前php指令碼。

再反過來看單例模式

 

 1 class A 2 { 3     private static $instance = null; 4     private $b = 1; 5     public static function get_instance() 6     { 7         if(self::$instance == null){ 8             $classname = __CLASS__; 9             self::$instance = new $classname(); 10         }11         return self::$instance;12     }13     public function add()14     {15         $this->b++;16     }17     public function show()18     {19         echo $this->b;20     }21 }22 $a = A::get_instance();23 $b = A::get_instance();24 //此處$a和$b 變數完全相同!25 $a->add();26 $a->show();27 echo ‘28 ‘;29 $b->show();30 //output31 //232 //2

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

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

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

 

 1 class A 2 { 3     private static $instance = null; 4     private $b = 1; 5     private function __construct() 6     { 7     //Code in this function 8     //could not be get out of the class 9     }10     public static function get_instance()11     {12         if(self::$instance == null){13             $classname = __CLASS__;14             self::$instance = new $classname();15         }16         return self::$instance;17     }18     public function add()19     {20         $this->b++;21     }22     public function show()23     {24         echo $this->b;25     }26 }27 $a = A::get_instance();28 $b = A::get_instance();29 //此處$a和$b 變數完全相同!30 $a->add();31 $a->show();32 echo ‘33 ‘;34 $b->show();35 //output36 //237 //238   39 //如果嘗試用new來執行個體化的話40 $c = new A();41 //output42 //Fatal error: Call to private A::__construct() from invalid context in43 //如果需要A類的執行個體化對象,只能通過開放的get_instance靜態方法進行初始化

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

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

文章來源:http://blog.chinaunix.net/uid-25979788-id-3220510.html

 

單例模式與靜態變數在PHP中

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.