本文針對已有 PHP 基礎的開發者,系統梳理類結構、構造/析構、可見性、魔術方法、繼承機制、重載與靜態延遲綁定等核心概念,並附代碼實例驗證行為差異。
class Person {
private $name = 'PersonName';
public static $gender = 'PersonGender';
public function test() { echo $this->name . '
'; }
}
關鍵差異:PHP **不會**自動調用父類構造函數,需手動 `parent::__construct()`。
class Person {
public function __construct() { echo 'Person construct
'; }
}
class Teacher extends Person {
public function __construct() {
parent::__construct(); // 必須手動調用
echo 'Teacher construct
';
}
}
$t = new Teacher; // 輸出:Person construct → Teacher construct
多構造函數模擬:PHP 不支援多載,利用 `func_get_args()` 實現:
public function __construct() {
$args = func_get_args();
$count = func_num_args();
if ($count === 0) { /* ... */ }
elseif ($count === 1 && is_array($args[0])) { /* ... */ }
}
物件銷毀前自動調用,繼承時同樣需手動 `parent::__destruct()`,每類僅能有一個。
| 關鍵字 | 類內 | 子類 | 類外 |
|---|---|---|---|
| public | ✓ | ✓ | ✓ |
| protected | ✓ | ✓ | ✗ |
| private | ✓ | ✗ | ✗ |
用於攔截不可見屬性的存取,實現資料驗證、日誌、代理等:
class D {
public $name = 'D name';
protected $gender = 'male';
private $age = 18;
public function __set($name, $value) {
$allow = ['gender', 'age'];
if (in_array($name, $allow)) $this->$name = $value;
}
public function __get($name) {
$allow = ['gender', 'age'];
return in_array($name, $allow) ? $this->$name : null;
}
public function __isset($name) { return isset($this->$name); }
public function __unset($name) { $allow = ['tail']; if (in_array($name, $allow)) unset($this->$name); }
}
注意:`public` 屬性**不會**觸發 `__get`/`__set`,必須是 `protected` 或 `private`。
子類繼承父類,父類無法存取子類成員。
| 父類可見性 | 子類重寫 | 父類方法內存取 $this->prop | 子類方法內存取 $this->prop |
|---|---|---|---|
| public | public | 子類值 | 子類值 |
| private | public | 父類值(私有不繼承) | 子類值 |
| protected | protected/public | 子類值 | 子類值 |
原則:`private` 成員在定義它的類中存取時,永遠綁定該類自己的值。
class G {
public static $attr = 'G';
public function oper() { echo self::$attr; } // 永遠輸出 G
}
class H extends G {
public static $attr = 'H';
public function oper() { echo static::$attr; } // 輸出 H(延遲綁定)
}
class I {
public static function who() { echo __CLASS__; }
public static function test() { static::who(); }
}
class J extends I {
public static function who() { echo __CLASS__; }
}
J::test(); // 輸出 J
深入理解這些機制,能寫出更健壯、可維護、可擴展的 PHP 面向對象代碼。