首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 構造方法與解構方法:__construct、__destruct、物件生命週期管理

     編輯:PHP 綜合知識

構造方法 __construct()

  • 物件實例化(new Class())後自動調用的第一個方法。
  • 用途:初始化屬性、建立資源連線(DB、Redis、檔案句柄)、註冊事件監聽、驗證必需參數。
  • PHP 4 風格:同名方法 function ClassName()(已棄用)。
  • PHP 5+:統一使用 __construct(),類別重命名不影響構造方法名。
  • 可接收參數,支援類型提示、預設值、可變參數。

解構方法 __destruct()

  • 物件被銷毀(引用計數歸零、腳本結束、unset($obj)、超出作用域)前自動調用的最後一個方法。
  • 用途:釋放資源(關閉連線、關閉檔案、釋放鎖)、記錄日誌、緩衝區刷新、發送關閉通知。
  • PHP 使用垃圾回收機制(GC),非確定性銷毀時間(請求結束前批量清理)。
  • 異常處理:解構方法中不可拋出異常(會導致 Fatal Error),需內部 try-catch。

程式碼範例

<?php
class Database {
    private $pdo;
    private $queryLog = [];

    public function __construct(string $dsn, string $user, string $pass) {
        echo "Database 建構子:建立連線<br>";
        $this->pdo = new PDO($dsn, $user, $pass, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    }

    public function query(string $sql) {
        $this->queryLog[] = $sql;
        return $this->pdo->query($sql)->fetchAll();
    }

    public function __destruct() {
        echo "Database 解構子:關閉連線、寫入查詢日誌<br>";
        // 寫入日誌檔案
        file_put_contents('/tmp/query.log', implode("\n", $this->queryLog) . "\n", FILE_APPEND);
        $this->pdo = null; // 顯式斷開(雖然腳本結束會自動)
    }
}

// 使用
$db = new Database('mysql:host=localhost;dbname=test', 'root', '');
$users = $db->query('SELECT * FROM users');
// 腳本結束自動調用 __destruct
?>

繼承中的構造/解構鏈

<?php
class ParentClass {
    public function __construct() {
        echo "Parent __construct<br>";
    }
    public function __destruct() {
        echo "Parent __destruct<br>";
    }
}

class ChildClass extends ParentClass {
    public function __construct() {
        parent::__construct(); // 必須顯式調用
        echo "Child __construct<br>";
    }
    public function __destruct() {
        echo "Child __destruct<br>";
        parent::__destruct(); // 必須顯式調用
    }
}

$obj = new ChildClass();
/*
輸出順序:
Parent __construct
Child __construct
...腳本結束...
Child __destruct
Parent __destruct
*/
?>

常見陷阱與最佳實踐

陷阱後果解決
子類未調用 parent::__construct()父類初始化邏輯缺失(連線未建、屬性未初始化)強制規範:子類構造首行調用
__destruct 拋出異常Fatal Error: Exception thrown without a stack frame內部 try-catch 吞噬或記錄
循環引用導致延遲銷毀資源釋放滯後、記憶體洩漏PHP 5.3+ GC 自動處理;手動 unset 打破循環
依賴 __destruct 執行關鍵業務(寫入 DB)請求異常終止時可能不執行關鍵操作顯式調用 save()/commit(),不依賴解構子

現代替代:PHP 8.1+ __serialize/__unserialize 與資源管理

配合 WeakReference、Finalizer(PECL)、register_shutdown_function 實現更可控的生命週期管理。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved