初學 PHP 的開發者常對解構函式感到陌生。本文將詳細解析 PHP 物件導向中的建構函式(`__construct`)與解構函式(`__destruct`),幫助你掌握物件生命週期的核心機制,優化記憶體管理。
大多數類別都擁有名為 `__construct()` 的特殊方法。當使用 `new` 關鍵字實例化物件時,PHP 會自動呼叫此方法,通常用於執行初始化任務,如設定預設屬性值、建立資料庫連線等。
PHP 5 引入 `__construct` 統一命名,舊版本需使用與類別同名的方法。為相容舊代碼,若類別無 `__construct`,PHP 會嘗試尋找同名方法。
<?php
class Person {
public $name;
public $age;
function __construct() {
$this->name = "Li Si";
$this->age = 28;
}
function say() {
echo "My name is " . $this->name . "<br/>";
echo "My age is " . $this->age . "<p>";
}
}
$per = new Person();
$per->say();
$per->name = "Zhang San";
$per->age = 26;
$per->say();
?>
解構函式 `__destruct()` 是 PHP 5 新增功能,PHP 4 無此概念。它允許在物件被銷毀前執行清理操作(如關閉資源、寫入日誌)。當所有指向該物件的引用被釋放或超出作用域時,PHP 會自動呼叫它。解構函式不能接受任何參數。
<?php
class Person {
function __destruct() {
echo "Bye bye!";
}
}
$a = new Person();
?>
子類別繼承父類別時,若子類別定義了自己的 `__construct`,父類別的建構函式**不會**自動執行。若需呼叫父類別建構函式,必須在子類別中顯式使用 `parent::__construct()`。
<?php
class Base {
function __construct() {
echo "Base constructor called.<br/>";
}
}
class Derived extends Base {
function __construct() {
parent::__construct(); // 显式调用父类构造函数
echo "Derived constructor called.<br/>";
}
}
$obj = new Derived();
?>
PHP 早期版本以類別名稱作為建構函式名稱。PHP 5 仍支援此寫法:若類別同時擁有 `__construct` 和同名方法,`__construct` 優先。這確保舊代碼仍能運作,但新代碼應統一使用 `__construct`,好處是更改類別名稱時無需修改建構函式名稱。
建構函式可設為 `public`、`protected` 或 `private`。將其設為 `private` 可防止外部直接實例化,這是實現**單例模式**的關鍵手段之一。
PHP 預設會自動釋放物件屬性佔用的記憶體。解構函式讓開發者能在物件銷毀前執行自定義清理邏輯。物件銷毀時機:函數內的區域物件在 `return` 時;全域物件在腳本結束時;或手動將變數設為 `null` / 呼叫 `unset()`。
利用靜態屬性配合建構/解構函式,可追蹤類別實例數量:
<?php
class Counter {
private static $count = 0;
function __construct() {
self::$count++;
}
function __destruct() {
self::$count--;
}
function getCount() {
return self::$count;
}
}
$c = new Counter();
echo $c->getCount() . "<br/>"; // 1
$c2 = new Counter();
echo $c->getCount() . "<br/>"; // 2
$c2 = null; // 显式销毁
echo $c->getCount() . "<br/>"; // 1
?>
輸出結果:
1
2
1