首頁  >  文章  >  後端開發  >  php析構函數的一個問題解決

php析構函數的一個問題解決

黄舟
黄舟原創
2017-07-02 10:15:411096瀏覽

  隨著物件導向程式設計的普遍展開,物件導向展現了其中許多有趣的問題。相信很多初學者學習php物件導向時會接觸兩個函數,建構函數析構函數。構造函數似乎用的更多,析構函數用的較少(相對初學者有限編程經驗而言,筆者也是如此。)在函數上,構造函數在創建對象時調用,析構函數在物件銷毀時調用,都無需特意去調用,一頭一尾,倒也是前後照應。

  析構函數常常處理的事務是一些資源釋放的工作,例如前面有fopen(),這裡呼叫fclose(),前面有imagecreatefromjepg(),這裡呼叫imagedestory(),這些都是些常見的例子,當然不限於此。我們大可將其當做一個普通的會在物件銷毀或腳本執行完畢#的時候執行的函數。

  囉嗦那麼多,還是儘早提出今天的主要的問題:

<?php
class Test{
    public function destruct(){
        echo "执行析构函数";
    }
 }
$test1=new Test;
$test2=$test3=$test1;
unset($test1);
echo "<hr/>";

  這段腳本執行結果是什麼?

  在回答這個問題之前,回看我上面標示的幾個字。我們可以理所當然的認為在輸出分隔線前 unset($test1) ,這樣會呼叫析構函數,輸出文字,至於  $test2,$test3 應該會在腳本執行完成後呼叫析構函數。也就是說,在分割線上面,會輸出一段文字,分隔線下面會輸出兩段文字。 在這個時候,大可以小驕傲一下,畢竟自己懂得什麼時候呼叫析構函數。但現實真是如此?我們可以看一下執行結果。

  

  嘿,他喵的,怎麼就輸出了一句啊? ? ?

  其實我們忽略了一個重要的前提條件,就是物件的賦值預設的是引用賦值。這一點很多人沒有註意到,希望初學者能多注意一點。

  那麼既然是引用賦值,結合我們對普通變數的理解,我們很快想到,三個變數名稱指向同一塊儲存位址。那麼既然如此的話, unset($test1) 起到的是什麼作用? ? ?破壞變數指向儲存位址還是破壞儲存位址儲存的內容?

  了解unset()函數用法的請直覺跳過本段。

  想著這蛋痛的問題,莫不如去查看手冊。

  同樣是傳遞引用,毀掉的只是變數名稱指向儲存位址。結合平常unset()的作用,我們可以這麼描述,當多個變數名稱或物件名稱指向一塊儲存位址時,unset()函數的作用僅僅是銷毀變數名稱和儲存位址的指向而已,當只有一個變數名或物件名,unset銷毀的是指定的儲存位址上的內容。

  我們可以想像真實的儲存內容是一台電視。多個人(多個變數名稱或物件名稱)在看一台電視。 unset()後,一個人不看了,離開了,電視還開著。當只有一個人看電視的時候,unset()後,人離開的時候,要把電視關了 ,也就是釋放佔用的存儲空間。對這部分內容有興趣的話也可以看一下《php 遞迴函數的三種實作方式》。

  好的,回歸主題。 unset($test1) 後, 原來的物件還在。當輸出分割線後,腳本執行完畢,呼叫析構函數。 因為物件只有一個,呼叫析構函數也只呼叫一次。輸出如上結果也就理所當然。

 

  其他幾個相關的有意思的問題:在程式中呼叫析構函數的方法還有很多。無論是設定物件為null,或false,其餘的物件依舊不受影響。這和普通變數還是有差別的。 (unset()函數的效果是一樣的)。有興趣的話可以試試。

  另外說一個比較囧的事情:我們都知道建構子可以使用construct(),卻忽略了同名建構子。所以,大家還是留心。

 

以上是php析構函數的一個問題解決的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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