隨著物件導向編程的普遍展開,物件導向展現了其中很多有趣的問題。相信很多初學者學習php物件導向時會接觸兩個函數,建構函式與解構函式。建構函式似乎用的更多,解構函式用的較少(相對初學者有限編程經驗而言,筆者也是如此。)在功能上,建構函式在建立對象時調用,解構函式在對象銷毀時調用,都無需特意去調用,一頭一尾,倒也是前後照應。
解構函式常常處理的事務是一些資源釋放的工作,比如前面有fopen(),這裡調用fclose(),前面有imagecreatefromjepg(),這裡調用imagedestory(),這些都是些常見的例子,當然不局限於此。我們大可將其當做一個普通的會在對象銷毀或者指令碼執行完畢的時候執行的函數。
囉嗦那麼多,還是儘早提出今天的主要的問題:
<?phpclass Test{ public function __destruct(){ echo "執行解構函式"; } }$test1=new Test;$test2=$test3=$test1;unset($test1);echo "<hr/>";
這段指令碼執行結果是什嗎?
在回答這個問題之前,回看我上面標示的幾個字。我們可以理所應當的認為在輸出分隔線前 unset($test1) ,這樣會調用解構函式,輸出文字,至於 $test2,$test3 應該會在指令碼執行完畢調用解構函式。也就是說,在分割線上面,會輸出一段文字,分隔線下面會輸出兩段文字。 在這個時候,大可以小驕傲一下,畢竟自己懂得什麼時候調用解構函式。但現實真是如此嗎?我們可以看一下執行結果。
嘿,他喵的,怎麼就輸出了一句啊???
其實我們忽略了一個重要的前提條件,就是對象的賦值預設的是引用賦值。這一點很多人沒有注意到,希望初學者能多多注意一下。
那麼既然是引用賦值,結合我們對普通變數的理解,我們很快想到,三個變數名指向同一Block Storage地址。那麼既然如此的話, unset($test1) 起到的是什麼作用???破壞變數指向儲存地址還是破壞儲存地址儲存的內容?
瞭解unset()函數用法的請直覺跳過本段。
想著這蛋疼的問題,莫不如去查看手冊。
同樣是傳遞引用,毀掉的僅僅是變數名指向儲存地址。結合平常unset()的作用,我們可以這麼描述,當多個變數名或者對象名指向一Block Storage地址時,unset()函數的作用僅僅是銷毀變數名和儲存地址的指向而已,當僅有一個變數名或者對象名,unset銷毀的是指定的儲存地址上的內容。
我們可以想象真實的儲存內容是一台電視。多個人(多個變數名或對象名)在看一台電視。unset()後,一個人不看了,離開了,電視還開著。當只有一個人看電視的時候,unset()後,人離開的時候,要把電視關了 ,也就是釋放佔用的儲存空間。對這部分內容感興趣的話也可以看一下《php 遞迴函式的三種實現方式》。
好的,迴歸主題。 unset($test1) 後, 原來的對象還在。當輸出分割線後,指令碼執行完畢,調用解構函式。 因為對象只有一個,調用解構函式也只調用一次。輸出如上結果也就理所應當。
其他幾個相關的有意思的問題:在程式中調用解構函式的方法還有很多。無論是設定對象為null,還是false,其餘的對象依舊不受影響。這和普通變數還是有區別的。(unset()函數的效果是一樣的)。有興趣的話可以試試。
另外說一個比較囧的事情:我們都知道建構函式可以使用__construct(),卻忽視了同名建構函式。所以,大家還是留心一下。
最後我們來看個例子
<?php /* * Created on 2009-11-18 * * To change the template for this generated file go to * Window - Preferences - PHPeclipse - PHP - Code Templates */ class student{ //屬性 private $no; private $name; private $gender; private $age; private static $count=0; function __construct($pname) { $this->name = $pname; self::$count++; } function __destruct() { self::$count--; } static function get_count() { return self::$count; } } $s1=new student("Tom"); print(student::get_count()); $s2=new student("jerry"); print(student::get_count()); $s1=NULL; print(student::get_count()); $s2=NULL; print(student::get_count()); ?>
上面這段代碼就是PHP5解構函式的具體使用方法,希望對大家有所協助。