我們在創建和銷毀對象時需要執行一些任務。例如,在創建對象時給屬性賦值,在對象銷毀時關閉數據連接等,這時就需要構造函數和析構函數。
在PHP中構造函數和析構函數是固定的,如下:
// 構造函數 function __construct([argument1,argument2,...,argumentN]){ /* Class initialization code */ } // 析構函數 function __destruct(){ // ... }
構造函數
- 構造函數可以接受參數,能夠在創建對象時賦值給對象屬性
- 構造函數可以調用類方法或其他函數
- 構造函數可以調用其他類的構造函數
構造函數使用例子:
<?php class Person{ private $name; private $age; private $gender; public function __construct($name,$age,$gender){ $this->setName($name); $this->setAge($age); $this->setGender($gender); } public function setName($name){ $this->name = $name; } // ... getter setter 方法 } $peron = new Person("lee",18,'男'); ?>
調用父類構造函數、調用無關類的構造函數:
function __construct(){ parent::__construct(); // 調用父類的構造函數必須顯示的使用parent調用父類構造函數 classname::__construct(); // 調用其他類的構造函數,classname是類名 //其他操作 }
繼承和構造函數
PHP中的子類的構造函數不會主動調用父類的構造函數,要顯示的使用parent::__construct()調用:
<?php class Animal{ private $name; function __construct($name){ $this->setName($name) echo "動物類被創建!"; } // ... 其他方法 } class Birds extends Animal{ private $name; private $leg; function __construct($name,$leg){ parent::__construct($name); // 顯示調用 $this->setLeg($leg); echo "鳥類被創建!"; } // ... 其他方法 } ?>
如果涉及多層繼承,當調用parent::__construct()時,會沿着父類向上搜索,直到找到最合適的構造函數,例如:
// 接上例 class Parrot extends Birds{ private $name; private $leg; private $wing; function __construct($name){ parent::__construct($name); // 此時沒有找到父類(Birds類)合適的構造函數,只能向上搜索,搜索到Animal類時,才找到合適的構造函數 echo "鸚鵡類被創建!"; $this->smackTalk(); /* 輸出結果: "動物類被創建!" "鸚鵡說話!" */ } function smackTalk(){ echo "鸚鵡說話!"; } }
如果想要依次調用幾個父類的構造函數,可以使用類名直接調用構造函數,例如:
function __construct($name,$leg){ Animal::__construct($name); // 調用Animal構造函數 Birds::__construct($name,$leg); // 調用Birds構造函數 }
PHP是不支持函數的重載,所有構造函數同樣不能有多個。
析構函數
- 析構函數是在銷毀對象時,自動調用,不能顯示的調用。
- 析構函數不能帶參數。
在以下幾種情況下可能會調用析構函數(但不一定):
- PHP頁面加載完畢之后;
- unset()類;
- 變量引用指向別的對象或值時;
PHP的內存回收機制和JAVA的很類似,對沒有任何引用的對象進行銷毀回收,采用引用計數器的技術。
例子:
<?php class test{ function __destruct(){ echo "當對象銷毀時會調用!!!"; } } $a = $b = $c = new test(); $a = null; unset($b); echo "<hr />"; ?>
此例子,如下圖,有三個變量引用$a,$b,$c指向test對象,test對象就有3個引用計數,當$a = null時,$a對test對象的引用丟失,計數-1,變為2,當$b被unset()時,$b對test對象的引用也丟失了,計數再-1,變為1,最后頁面加載完畢,$c指向test對象的引用自動被釋放,此時計數再-1,變為0,test對象已沒有變量引用,就會被銷毀,此時就會調用析構函數。