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

PHP 魔術方法實戰匯總:10 大核心魔術方法完整代碼示範

     編輯:PHP 綜合知識

魔術方法核心清單

配對/單獨方法觸發情境
配對__construct / __destruct建構/銷毀物件
配對__get / __set讀寫不可存取屬性
配對__isset / __unsetisset/unset 不可存取屬性
配對__call / __callStatic呼叫不可存取方法/靜態方法
配對__sleep / __wakeup序列化/反序列化
單獨__cloneclone 複製物件
單獨__toString物件轉字串
單獨__invoke物件當函數呼叫
單獨__set_statevar_export 匯出類別
單獨__debugInfovar_dump 除錯輸出 (PHP 5.6+)

完整實作類別

<?php
class Magic {
    public $var = 'test';

    public function __construct() {
        echo '__construct called' . PHP_EOL;
    }
    public function __destruct() {
        echo '__destruct called' . PHP_EOL;
    }
    public function __set($name, $value) {
        echo $name . '-' . $value . '__set called' . PHP_EOL;
    }
    public function __get($name) {
        echo $name . '__get called' . PHP_EOL;
    }
    public function __call($name, $args) {
        echo $name . '-' . implode(',', $args) . '__call called' . PHP_EOL;
    }
    public static function __callStatic($name, $args) {
        echo $name . '-' . implode(',', $args) . '__callStatic called' . PHP_EOL;
    }
    public function __isset($name) {
        echo $name . '__isset called' . PHP_EOL;
        return true;
    }
    public function __unset($name) {
        echo $name . '__unset called' . PHP_EOL;
    }
    public function __sleep() {
        echo '__sleep called' . PHP_EOL;
        return ['var1111111111']; // 故意回傳不存在屬性示範
    }
    public function __wakeup() {
        echo '__wakeup called' . PHP_EOL;
        $this->var = 'test after wakeup';
    }
    public function __toString() {
        return '__toString called' . PHP_EOL;
    }
    public function __clone() {
        echo '__clone called' . PHP_EOL;
    }
    public function __invoke() {
        echo '__invoke called' . PHP_EOL;
    }
    public static function __set_state($arr) {
        return '__set_state called' . PHP_EOL;
    }
    public function __debugInfo() {
        echo '__debugInfo called' . PHP_EOL;
        return ['var' => 'test from __debugInfo'];
    }
}

// 完整測試流程
$m = new Magic();                          // __construct
$m->not_exist_property = 'test';           // __set
echo $m->not_exist_property;               // __get
$m->abc(1, 2, 3);                          // __call
Magic::staticMethod(1, 2, 3);              // __callStatic
echo isset($m->not_exist_property);        // __isset (回傳 bool)
unset($m->not_exist_property);             // __unset
$tmp = serialize($m);                      // __sleep
unserialize($tmp);                         // __wakeup
$m1 = clone $m;                            // __clone
$m();                                      // __invoke
eval('$m2 = ' . var_export($m, true) . ';'); // __set_state
var_dump($m2);
var_dump($m);                              // __debugInfo
// 程式結束觸發 __destruct (多個物件依序)

執行結果輸出

__construct called
not_exist_property-test__set called
not_exist_property__get called
abc-1,2,3__call called
not_exist_property__isset called
1
not_exist_property__unset called
__sleep called
O:5:"Magic":1:{s:13:"var1111111111";N;}
__wakeup called
__destruct called
__clone called
__invoke called
string(20) "__set_state called "
class Magic#1 (1) {
  public $var => string(4) "test"
}
__destruct called
__destruct called

關鍵觀察重點

  1. __sleep 回傳的屬性名若不存在,序列化結果為 N; (null)
  2. __wakeup 可修改物件狀態 (範例中重設 $var)
  3. __clone 發生於 clone 關鍵字操作後,預設為淺複製
  4. __invoke 讓物件具備可呼叫性,配合 is_callable() 判斷
  5. __set_state 為 靜態方法,接收陣列參數回傳物件實例
  6. __debugInfo 讓 var_dump 只顯示指定屬性,保護敏感資料
  7. 多物件銷毀順序:後建立先銷毀 (堆疊式)

實務應用場景

  • ORM 模型:__get/__set 實現屬性映射、__sleep 排除 PDO 連線
  • 動態代理:__call 轉發至遠端服務
  • 單例模式:__clone 拋出異常防複製
  • DTO 序列化:__sleep/__wakeup 控制快取內容
  • 除錯安全:__debugInfo 隱藏密碼、Token

相關專題

  • 《PHP 基本語法入門教程》
  • 《PHP 錯誤與異常處理方法總結》
  • 《PHP 常用函數與技巧總結》
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved