關於php析構函數的一個有趣問題 php 遞歸函數的三種實現方式

  隨着面向對象編程的廣泛展開,面向對象展示了其中不少有趣的問題。相信不少初學者學習php面向對象時會接觸兩個函數,構造函數與析構函數。構造函數彷佛用的更多,析構函數用的較少(相對初學者有限編程經驗而言,筆者也是如此。)在功能上,構造函數在建立對象時調用,析構函數在對象銷燬時調用,都無需特地去調用,一頭一尾,倒也是先後照應。php

  析構函數經常處理的事務是一些資源釋放的工做,好比前面有fopen(),這裏調用fclose(),前面有imagecreatefromjepg(),這裏調用imagedestory(),這些都是些常見的例子,固然不侷限於此。咱們大可將其當作一個普通的會在對象銷燬或者腳本執行完畢的時候執行的函數。html

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

<?php
class
Test{ public function __destruct(){ echo "執行析構函數"; } } $test1=new Test; $test2=$test3=$test1;
unset($test1);
echo "<hr/>";

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

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

  

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

  其實咱們忽略了一個重要的前提條件,就是對象的賦值默認的是引用賦值。這一點不少人沒有注意到,但願初學者能多多注意一下。url

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

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

  想着這蛋疼的問題,莫不如去查看手冊。htm

  一樣是傳遞引用,毀掉的僅僅是變量名指向存儲地址。結合日常unset()的做用,咱們能夠這麼描述,當多個變量名或者對象名指向一塊存儲地址時,unset()函數的做用僅僅是銷燬變量名和存儲地址的指向而已,當僅有一個變量名或者對象名,unset銷燬的是指定的存儲地址上的內容。

  咱們能夠想象真實的存儲內容是一臺電視。多我的(多個變量名或對象名)在看一臺電視。unset()後,一我的不看了,離開了,電視還開着。當只有一我的看電視的時候,unset()後,人離開的時候,要把電視關了 ,也就是釋放佔用的存儲空間。對這部份內容感興趣的話也能夠看一下《php 遞歸函數的三種實現方式》。

  

  好的,迴歸主題。 unset($test1) 後, 原來的對象還在。當輸出分割線後,腳本執行完畢,調用析構函數。 由於對象只有一個,調用析構函數也只調用一次。輸出如上結果也就理所應當。

 

  其餘幾個相關的有意思的問題:在程序中調用析構函數的方法還有不少。不管是設置對象爲null,仍是false,其他的對象依舊不受影響。這和普通變量仍是有區別的。(unset()函數的效果是同樣的)。有興趣的話能夠試試。

  另外說一個比較囧的事情:咱們都知道構造函數能夠使用__construct(),卻忽視了同名構造函數。因此,你們仍是留心一下。

相關文章
相關標籤/搜索