1. 類別基礎與可見性
<?php
class User {
public string $name; // 公開
protected int $age; // 繼承類別可存取
private string $password; // 僅本類別可存取
public function __construct(string $name, int $age, string $pwd) {
$this->name = $name;
$this->age = $age;
$this->password = $pwd;
}
public function __destruct() {
// 物件銷毀前執行 (資源釋放、記錄日誌)
}
// 魔術方法:讀取不可見屬性
public function __get(string $prop) {
return $this->$prop ?? null;
}
// 魔術方法:寫入不可見屬性
public function __set(string $prop, mixed $val): void {
if ($prop === 'password') {
$this->password = password_hash($val, PASSWORD_DEFAULT);
}
}
}
?>
2. 繼承與父類別呼叫
class Admin extends User {
public function __construct(string $name, int $age, string $pwd, public string $role) {
parent::__construct($name, $age, $pwd); // 呼叫父建構子
}
public function promote(): void {
parent::someMethod(); // :: 範圍解析運算子呼叫父方法
}
}
3. 關鍵字詳解
| 關鍵字 | 用途 | 限制 |
final | 類別不可繼承 / 方法不可覆寫 | |
static | 靜態屬性/方法,屬於類別而非實例 | 靜態方法內不可用 $this |
const | 類別常數,不加 $ 符號 | 值必須為常量表達式 |
self | 存取靜態成員/常數 (晚期靜態綁定用 static) | |
abstract | 抽象類別/方法,強制子類別實作 | 不可實例化 |
interface | 介面定義契約,全為 public 抽象方法 | 可多重實作 (implements) |
trait | 程式碼複用單位,可在類別中 use | 不可實例化 |
4. 介面與多型
interface Loggable {
public function log(string $msg): void;
}
class FileLogger implements Loggable {
public function log(string $msg): void {
file_put_contents('app.log', $msg . PHP_EOL, FILE_APPEND);
}
}
class DbLogger implements Loggable {
public function log(string $msg): void {
// 寫入資料庫
}
}
// 多型:同一介面不同實作
function process(Loggable $logger) {
$logger->log('處理完成');
}
process(new FileLogger());
process(new DbLogger());
5. 物件複製與比較
$user1 = new User('Tom', 25, 'secret');
$user2 = clone $user1; // 淺層複製
// 深層複製需實作 __clone()
class User {
// ...
public function __clone() {
$this->relatedObject = clone $this->relatedObject;
}
}
// instanceof 型別檢查
if ($user1 instanceof User) { /* ... */ }
if ($user1 instanceof Loggable) { /* ... */ }
6. 魔術方法補充
__toString():echo $obj 時自動呼叫,需回傳字串
__call($name, $args):呼叫不存在方法時觸發 (Proxy 模式常用)
__callStatic():靜態版本
__invoke():物件當函數呼叫 $obj()
__sleep()/__wakeup():序列化控制
7. 自動載入 (PSR-4)
spl_autoload_register(function (string $class) {
$file = __DIR__ . '/src/' . str_replace('\\', '/', $class) . '.php';
if (is_file($file)) require $file;
});
// 或使用 Composer 自動產生 vendor/autoload.php