自 PHP 5.4 引入,Trait 是為單繼承語言設計的代碼復用機制,允許在不同類別層級間水平組合方法。本文系統整理 Trait 定義、使用、優先順序、衝突解決、嵌套、抽象方法、屬性、可見性調整等核心特性,附完整可執行範例。
hello(); // hello
echo $obj->world(); // world
當前類別方法 > Trait 方法 > 父類別方法
say(); // 輸出 Trait (Child 未覆寫時)
hello(); // hello
$obj->world(); // world
write($msg); // 呼叫抽象方法
}
abstract public function write($msg); // 強制實作
}
class FileLogger {
use LoggerTrait;
public function write($msg) { file_put_contents('log.txt', $msg . PHP_EOL, FILE_APPEND); }
}
class DbLogger {
use LoggerTrait;
public function write($msg) { /* DB 寫入 */ }
}
smallTalk(); // b
$t1->bigTalk(); // A
$t2 = new AliasedTalker();
$t2->talk(); // B (呼叫別名方法)
x; // 1
// echo $e->y; // Fatal error: Cannot access protected property
| 情況 | 結果 |
|---|---|
| Trait 與類別定義同名屬性,可見性與初始值相同 | E_STRICT 警告 |
| Trait 與類別定義同名屬性,可見性或初始值不同 | Fatal Error (編譯錯誤) |
| 兩個 Trait 定義同名屬性 | Fatal Error (無法用 insteadof 解決屬性衝突) |
trait Loggable { public function log($msg) { ... } }trait SoftDeletes { public function delete() { $this->deleted_at = time(); $this->save(); } }trait Serializable { public function toArray() { ... } }trait HttpClientAware { protected $client; public function setClient(Client $c) { $this->client = $c; } }$this 指向使用該 Trait 的類別實例。