萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 網路程式設計 >> PHP 程式設計

PHP 面向對象程式設計 (OOP) 核心概念與進階技術完整指南

PHP 面向對象程式設計 (OOP) 核心概念與進階技術完整指南

PHP 從 5.0 重寫物件模型,支援完整的封裝、繼承、多型,並引入介面、抽象類、Trait、屬性提升、唯讀屬性、Enum 等現代特性。本文系統整理 PHP OOP 核心語法、設計原則、進階模式與最佳實踐。

1. 類別、屬性、方法、建構子

<?php
declare(strict_types=1);

class User {
    // 可見度:public / protected / private
    // 唯讀屬性 (PHP 8.1+):初始化後不可修改
    public readonly string $id;
    public string $name;
    protected string $email;
    private string $passwordHash;

    // 型別宣告 + 預設值
    public function __construct(
        string $id,
        string $name,
        string $email,
        string $password
    ) {
        $this->id = $id;
        $this->name = $name;
        $this->email = $email;
        $this->passwordHash = password_hash($password, PASSWORD_DEFAULT);
    }

    // 方法
    public function getEmail(): string {
        return $this->email;
    }

    public function verifyPassword(string $password): bool {
        return password_verify($password, $this->passwordHash);
    }

    // 魔術方法:序列化控制
    public function __serialize(): array {
        return ['id' => $this->id, 'name' => $this->name, 'email' => $this->email];
    }
    public function __unserialize(array $data): void {
        $this->id = $data['id'];
        $this->name = $data['name'];
        $this->email = $data['email'];
        // passwordHash 不序列化,反序列化後需重新設定
    }
}
?>

2. 繼承、覆寫、final、abstract

<?php
abstract class Animal {
    protected string $name;

    public function __construct(string $name) {
        $this->name = $name;
    }

    // 抽象方法:子類必須實作
    abstract public function makeSound(): string;

    // 普通方法可被覆寫
    public function introduce(): string {
        return "我是 {$this->name}";
    }

    // final 方法禁止覆寫
    final public function getSpecies(): string {
        return static::class;
    }
}

class Dog extends Animal {
    public function makeSound(): string {
        return "汪汪!";
    }

    // 覆寫父類方法
    public function introduce(): string {
        return parent::introduce() . "," . $this->makeSound();
    }
}

$dog = new Dog('旺財');
echo $dog->introduce(); // 我是旺財,汪汪!
?>

3. 介面與多型

<?php
interface Payable {
    public function pay(float $amount): bool;
}

interface Refundable {
    public function refund(float $amount): bool;
}

// 多介面實作
class AlipayGateway implements Payable, Refundable {
    public function pay(float $amount): bool { /* ... */ return true; }
    public function refund(float $amount): bool { /* ... */ return true; }
}

class StripeGateway implements Payable {
    public function pay(float $amount): bool { /* ... */ return true; }
}

// 多型:依賴介面而非具體類
function checkout(Payable $gateway, float $amount): void {
    if ($gateway->pay($amount)) {
        echo "付款成功\n";
    }
}

checkout(new AlipayGateway(), 100.0);
checkout(new StripeGateway(), 50.0);
?>

4. Trait 程式碼複用 (橫向複用)

<?php
trait Loggable {
    protected function log(string $msg): void {
        error_log("[" . date('c') . "] $msg");
    }
}

trait Timestampable {
    public readonly DateTimeImmutable $createdAt;
    public ?DateTimeImmutable $updatedAt = null;

    public function touch(): void {
        $this->updatedAt = new DateTimeImmutable();
    }
}

class Order {
    use Loggable, Timestampable; // 多 Trait

    public function __construct(public string $id) {
        $this->createdAt = new DateTimeImmutable();
    }

    public function updateStatus(string $status): void {
        $this->log("Order {$this->id} status changed to $status");
        $this->touch();
    }
}
?>

5. 靜態成員、常數、晚期靜態綁定

<?php
class Config {
    public const VERSION = '1.0.0';
    private static ?self $instance = null;
    private array $settings = [];

    private function __construct() {}

    public static function getInstance(): self {
        return self::$instance ??= new self(); // PHP 8.0 nullsafe 賦值
    }

    public function set(string $key, mixed $value): void {
        $this->settings[$key] = $value;
    }

    public function get(string $key, mixed $default = null): mixed {
        return $this->settings[$key] ?? $default;
    }
}

// 晚期靜態綁定 (LSB)
class Base {
    public static function who(): string {
        return static::class; // 執行時解析為實際調用的類
    }
}
class Child extends Base {}
echo Child::who(); // "Child"
?>

6. 魔術方法精選

方法觸發時機常見用途
__constructnew 實例化初始化、依賴注入
__destruct物件銷毀釋放資源、關閉連線
__call / __callStatic呼叫不存在/不可見方法動態代理、流暢介面
__get / __set / __isset / __unset存取不存在/不可見屬性動態屬性、資料映射
__toString物件當字串用格式化輸出、ID 表示
__invoke物件當函數呼叫可呼叫物件、策略模式
__serialize / __unserialize序列化/反序列化 (PHP 7.4+)控制序列化內容、替代 Serializable
__cloneclone 物件深拷貝、重置 ID
__debugInfovar_dump()隱藏敏感屬性、自定義顯示

7. 設計原則與模式應用

  • SOLID:單一職責、開放封裡、里氏替換、介面隔離、依賴反轉。
  • 依賴注入 (DI):建構子注入、Setter 注入、介面綁定 (容器)。
  • 工廠模式:封裝複雜建構邏輯。
  • 策略模式:演算法封裝於獨立類,運行時切換 (如支付閘道)。
  • 觀察者/事件:解耦業務邏輯 (Symfony EventDispatcher, Laravel Events)。
  • Repository 模式:資料存取抽離,便於測試與切換儲存引擎。

8. 現代 PHP 8.x 新特性速覽

  • 屬性提升建構子:public function __construct(public string $name) {}
  • readonly 屬性/類:不可變物件。
  • Enum (PHP 8.1+):enum Status: string { case Draft = 'draft'; case Published = 'published'; }
  • Match 表達式:嚴格比較、無 break、回傳值。
  • Constructor Property Promotion + readonly:public function __construct(public readonly string $id) {}
  • DNF 型別 (PHP 8.2+):string&Countable|null。
  • readonly 類:readonly class Dto { public function __construct(public string $a) {} }

9. 序列化與儲存

<?php
$user = new User('u1', 'John', 'john@example.com', 'secret');

// 原生 serialize (不推薦跨版本/語言)
$serialized = serialize($user);
$restored = unserialize($serialized);

// JSON (跨語言、可讀、無行為)
$json = json_encode($user, JSON_THROW_ON_ERROR); // 需實作 JsonSerializable
$restored = json_decode($json, true); // 陣列,非物件

// 推薦:專用 DTO + 序列化庫 (symfony/serializer, spatie/data-transfer-object)
?>

總結

PHP OOP 已臻成熟,配合嚴格型別、靜態分析 (PHPStan Level 8+)、測試 (Pest/PHPUnit)、編碼標準 (PSR-12),可構建極高品質的企業級應用。關鍵在於:依賴介面、組合優於繼承、單一職責、不可變資料、領域建模。

copyright © 萬盛學電腦網 all rights reserved