如何正確理解PHP析構函式
如果你在一個類別中宣告一個函式,命名為construct,這個函式將會被當成一個建構子並在建立一個物件實例時被執行. 清楚地說,是兩個下劃線. 就像其它任何函數一樣,構造函數可能有參數或預設值. 你可以定義一個類別來建立一個物件並將其屬性全放在一個語句(statement)中.
你也可以定義一個名為destruct的函數,PHP將在物件被銷毀前呼叫這個函數. 它稱為PHP析構函數.
繼承是類別的一個強大功能.一個類別(子類別/衍生類別)可以繼承另一類別(父類別/基底類別)的功能.衍生類別將包含有基底類別的所有屬性和方法,並且可以在衍生類別中加上其他屬性和方法. 你也可以覆寫基底類別的方法和屬性. 就像3.1.2中顯示的,你可以用extends關鍵字來繼承一個類別.
你可能想知道建構子是如何被繼承的. 當它們和其它方法一起被繼承時,他們不會在創建對象時被執行.
如果你需要這個函數,你需要用第二章提到的::運算子. 它允許你指向一塊命名空間. parent指向父類別命名空間,你可以用parent::construct來呼叫父類別的建構子.
一些物件導向語言在類別之後命名建構函式. PHP的前幾個版本也是如此,到現在這種方法仍然有效.也就是:如果你把一個類別命名為Animal並且在其中建立一個命名也是Animal的方法,則這個方法就是建構子.如果一個類別的同時擁有construt建構子和與類別名稱相同的函式,PHP將把construct看作建構子.這使得用以前的PHP版本所寫的類仍然可以使用. 但新的腳本(PHP5)應當使用construct.
PHP的這種新的聲明構造函數的方法可以使構造函數有一個獨一無二的名稱,無論它所在的類的名稱是什麼. 這樣你在改變類別的名稱時,就不需要改變構造函數的名稱.
你可能在PHP中給構造函數一個像其它類方法一樣的訪問方式. 訪問方式將會影響從在一定範圍內實例化物件的能力. 這允許實現一些固定的設計模式,如Singleton模式.
PHP析構函數,相反於建構函式. PHP呼叫它們來將一個物件從記憶體中銷毀.預設,PHP僅僅釋放物件屬性所佔用的記憶體並銷毀物件相關的資源. 析構函數允許你在使用一個物件之後執行任意程式碼來清除記憶體.
當PHP決定你的腳本不再與物件相關時,PHP析構函數將被呼叫. 在一個函數的命名空間內,這會發生在函數return的時候. 對於全局變數,這發生於腳本結束的時候. 如果你想明確地銷毀一個對象,你可以給指向該物件的變數分配任何其它值. 通常將變數賦值勤為NULL或呼叫unset .
下面的例子中,計算從類別中實例化的物件的個數. Counter類從建構子開始增值,在PHP析構函數減值.
一旦你定義了一個類別,你可以用new來建立一個這個類別的實例. 類別的定義是設計圖,實例則是放在裝配線上的元件. New需要類別的名稱,並傳回該類別的一個實例. 如果建構子需要參數,你應當在new後輸入參數.
1 < ?php 2 3 class Counter { private static $count = 0; 4 5 function construct() { self::$count++; } 6 7 function destruct() { self::$count--; } 8 9 function getCount() { return self::$count; } } 10 11 //建立第一个实例 12 13 $c = new Counter(); 14 15 //输出1 16 17 print($c->getCount() . "<br>\n"); 18 19 //建立第二个实例 20 21 $c2 = new Counter(); 22 23 //输出2 24 25 print($c->getCount() . "<br>\n"); 26 27 //销毁实例 28 29 $c2 = NULL; 30 31 //输出1 32 33 print($c->getCount() . "<br>\n"); 34 35 ?>
當你新建了一個PHP析構函數實例,記憶體會被準備來儲存所有屬性. 每個實例有自己獨有的一組屬性. 但方法是由該類別的所有實例共享的.
PHP 5 允行開發者在一個類別中定義一個方法作為建構子。具有建構函式的類別會在每次建立新物件時先呼叫此方法,所以非常適合在使用物件之前做一些初始化工作。
Note: 如果子類別中定義了建構子則不會隱含地呼叫其父類別的建構子。要執行父類別的建構函數,需要在子類別的建構子中呼叫parent::construct()。如果子類別沒有定義建構函式則會如同一個普通的類別方法一樣從父類別繼承(假如沒有被定義為 private 的話)。
Example #1 使用新標準的建構子
<?phpclass BaseClass { function construct() { print "In BaseClass constructor\n"; } }class SubClass extends BaseClass { function construct() { parent::construct(); print "In SubClass constructor\n"; } }class OtherSubClass extends BaseClass { // inherits BaseClass's constructor} // In BaseClass constructor$obj = new BaseClass(); // In BaseClass constructor // In SubClass constructor$obj = new SubClass(); // In BaseClass constructor$obj = new OtherSubClass();?>
為了實現向後相容性,如果PHP 5 在類別中找不到 construct()函數也沒有從父類別繼承一個的話,它就會嘗試尋找舊式的建構函數,也就是和類別同名的函數。因此唯一會產生相容性問題的情況是:類別中已有一個名為 construct() 的方法卻被用於其它用途時。
与其它方法不同,当 construct() 被与父类 construct() 具有不同参数的方法覆盖时,PHP 不会产生一个 E_STRICT
错误信息。
自 PHP 5.3.3 起,在命名空间中,与类名同名的方法不再作为构造函数。这一改变不影响不在命名空间中的类。
Example #2 Constructors in namespaced classes
<?php namespace Foo; class Bar { public function Bar() { // treated as constructor in PHP 5.3.0-5.3.2 // treated as regular method as of PHP 5.3.3 } } ?>
void destruct ( void )
PHP 5 引入了析构函数的概念,这类似于其它面向对象的语言,如 C++。析构函数会在到某个对象的所有引用都被删除或者当对象被显式销毁时执行。
Example #3 析构函数示例
<?php class MyDestructableClass { function construct() { print "In constructor\n"; $this->name = "MyDestructableClass"; } function destruct() { print "Destroying " . $this->name . "\n"; } }$obj = new MyDestructableClass();?>
和构造函数一样,父类的析构函数不会被引擎暗中调用。要执行父类的析构函数,必须在子类的析构函数体中显式调用 parent::destruct()。此外也和构造函数一样,子类如果自己没有定义析构函数则会继承父类的。
析构函数即使在使用 exit() 终止脚本运行时也会被调用。在析构函数中调用 exit() 将会中止其余关闭操作的运行。
以上是php析構函數的範例程式碼分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!