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

PHP 學習筆記:封裝與魔術方法 (__get, __set, __isset, __unset) 實戰

     編輯:PHP 綜合知識

封裝核心

  • 屬性宣告為 private,對外不可直接存取。
  • 提供 public 的 getter/setter 控制讀寫邏輯(驗證、轉換、日誌)。
  • 方法亦可 private,隱藏內部實作細節。

魔術方法自動攔截

方法觸發時機參數
__get($name)讀取不可存取屬性(不存在或 private/protected)$name: 屬性名
__set($name, $value)寫入不可存取屬性$name, $value
__isset($name)對不可存取屬性呼叫 isset() 或 empty()$name
__unset($name)對不可存取屬性呼叫 unset()$name

完整範例:Person 類別

<?php
class Person {
    private $name;
    private $age;
    private $sex;

    public function __construct($name, $age, $sex) {
        $this->name = $name;
        $this->age = $age;
        $this->sex = $sex;
    }

    // 直接讀取私有屬性時自動呼叫
    private function __get($prop) {
        if ($prop === 'age' && $this->age > 40) return $this->age - 10; // 讀取邏輯
        return $this->$prop ?? null;
    }

    // 直接寫入私有屬性時自動呼叫
    private function __set($prop, $value) {
        if ($prop === 'age' && ($value > 100 || $value < 0)) return; // 驗證
        $this->$prop = $value;
    }

    private function __isset($prop) {
        return isset($this->$prop);
    }

    private function __unset($prop) {
        unset($this->$prop);
    }

    // 公開介面(建議慣用)
    public function setAge($age) {
        if ($age > 100 || $age < 0) return;
        $this->age = $age;
    }
    public function getAge() {
        if ($this->age < 30) return $this->age;
        if ($this->age < 40) return $this->age - 5;
        if ($this->age < 50) return $this->age;
        return $this->age - 15;
    }

    public function say() {
        echo "我是 {$this->name},{$this->getAge()} 歲,{$this->sex}
"; $this->run(); // 呼叫私有方法 } private function run() { echo '跑步中...
'; } } /* 測試 */ $p = new Person('張三', 25, '男'); $p->say(); // 正常輸出 $p->setAge(30); // 透過 setter echo $p->getAge(); // 透過 getter $p->age = 35; // 觸發 __set echo $p->age; // 觸發 __get unset($p->name); // 觸發 __unset echo isset($p->name) ? '存在' : '不存在'; // 觸發 __isset

最佳實務

  • 魔術方法適合動態屬性(如 ORM 模型對應資料表欄位)。
  • 固定屬性優先使用明確 getter/setter,IDE 支援好、靜態分析友善、效能稍佳。
  • 魔術方法中避免重型邏輯,影響除錯與效能。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved