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

PHP面向對象程式設計(OOP)核心概念與實戰範例

     編輯:PHP 相關知識

PHP OOP 關鍵字與特殊語法速查

關鍵字/符號用途說明
class定義類藍圖/模板
new實例化建立物件實例
extends繼承單繼承,子類擁有父類非private成員
::範圍解析操作符訪問靜態成員、常數、覆蓋父類方法 parent::method()
$this偽變數指向當前實例,僅在物件上下文可用
self當前類靜態上下文訪問本類靜態成員,不支援晚期靜態綁定
parent父類訪問父類成員,避免硬編碼父類名
static靜態綁定PHP 5.3+ 晚期靜態綁定 (LSB),static::method()
final最終修飾類(不可繼承)或方法(不可覆蓋)
abstract抽象抽象類不可實例化;抽象方法無實現,強制子類實現
interface介面定義契約,所有方法隱含 public,支援多實現
implements實現介面類實現介面,必須實現所有方法
trait特質PHP 5.4+ 程式碼複用單位,解決單繼承限制

屬性與常數

<?php
class Product {
    // 可視性:public(預設) > protected > private
    public string $name = '';           // PHP 7.4+ 型別宣告
    protected float $price = 0.0;
    private int $stock = 0;
    
    // 常數:不可變,慣用大寫,不加 $ 符號
    public const TAX_RATE = 0.05;
    public const STATUS_ACTIVE = 1;
    
    // 唯讀屬性 PHP 8.1+
    public readonly string $sku;
    
    // 建構子屬性提升 PHP 8.0+
    public function __construct(
        public string $name,
        protected float $price,
        private int $stock = 0,
        public readonly string $sku = ''
    ) {
        $this->sku = $sku ?: 'SKU-' . uniqid();
    }
}

建構子與解構子

<?php
class DatabaseConnection {
    private $pdo;
    private $config;
    
    public function __construct(array $config) {
        $this->config = $config;
        // 注意:PHP 不會自動呼叫父類建構子
        // 必須顯式呼叫:parent::__construct($config);
    }
    
    public function connect(): void {
        $dsn = "mysql:host={$this->config['host']};dbname={$this->config['dbname']};charset=utf8mb4";
        $this->pdo = new PDO($dsn, $this->config['user'], $this->config['pass'], [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]);
    }
    
    // 解構子:物件銷毀時自動呼叫(請求結束或引用計數歸零)
    // ⚠️ 不能拋出異常,僅做資源清理
    public function __destruct() {
        $this->pdo = null; // 關閉連線
        // 不要在這裡做複雜邏輯或日誌寫入
    }
}

抽象類與介面:定義契約

抽象類:部分實現 + 強制契約

<?php
abstract class AbstractUser implements UserInterface {
    protected string $name = '';
    protected float $discount = 1.0;
    protected string $grade = 'Basic';
    
    public function __construct(string $name) {
        $this->setName($name);
    }
    
    // 具體實現:子類可直接使用或覆蓋
    public function getName(): string {
        return $this->name;
    }
    
    public function setName(string $name): void {
        $this->name = trim($name);
    }
    
    public function getDiscount(): float {
        return $this->discount;
    }
    
    public function getGrade(): string {
        return $this->grade;
    }
    
    // 抽象方法:強制子類實現
    abstract public function calculateShipping(float $amount): float;
}

介面:純契約,支援多實現

<?php
interface UserInterface {
    // 隱含 public abstract
    public function getName(): string;
    public function setName(string $name): void;
    public function getDiscount(): float;
    
    // 介面常數
    public const MAX_NAME_LENGTH = 50;
}

// 介面可繼承介面
interface PremiumUserInterface extends UserInterface {
    public function getPrioritySupport(): bool;
}

實戰範例:用戶等級折扣系統(策略模式雛形)

核心類定義

<?php
// User.php
interface UserInterface {
    public function getName(): string;
    public function setName(string $name): void;
    public function getDiscount(): float;
    public function getGrade(): string;
}

abstract class AbstractUser implements UserInterface {
    protected string $name = '';
    protected float $discount = 1.0;
    protected string $grade = 'Basic';
    
    public function __construct(string $name) {
        $this->setName($name);
    }
    
    public function getName(): string { return $this->name; }
    public function setName(string $name): void { $this->name = trim($name); }
    public function getDiscount(): float { return $this->discount; }
    public function getGrade(): string { return $this->grade; }
}

class NormalUser extends AbstractUser {
    protected float $discount = 1.0;
    protected string $grade = 'Normal';
}

class VipUser extends AbstractUser {
    protected float $discount = 0.8;
    protected string $grade = 'VIP';
}

class InnerUser extends AbstractUser {
    protected float $discount = 0.7;
    protected string $grade = 'Internal';
}

產品與結算邏輯(靜態工廠/服務類)

<?php
// Product.php
class Product {
    public function __construct(
        public string $name,
        public float $price
    ) {}
    
    public function getProductName(): string { return $this->name; }
    public function getProductPrice(): float { return $this->price; }
}

// ProductSettle.php - 結算服務
class ProductSettle {
    // 靜態方法:無狀態服務
    public static function finalPrice(UserInterface $user, Product $product, int $quantity = 1): float {
        return round($user->getDiscount() * $product->getProductPrice() * $quantity, 2);
    }
}

客戶端使用代碼

<?php
require_once 'User.php';
require_once 'Product.php';
require_once 'ProductSettle.php';

$quantity = 10;
$book = new Product('設計模式', 59.00);

$users = [
    new NormalUser('Tom'),
    new VipUser('Tom'),
    new InnerUser('Tom'),
];

foreach ($users as $user) {
    $price = ProductSettle::finalPrice($user, $book, $quantity);
    
    echo "您好,尊敬的用戶 {$user->getName()} <br>";
    echo "您的等級: {$user->getGrade()} <br>";
    echo "您的折扣: {$user->getDiscount()} <br>";
    echo "購買 {$quantity} 本《{$book->getProductName()}》價格: $price 元 <br><br>";
}

/*
輸出:
您好,尊敬的用戶 Tom
您的等級: Normal
您的折扣: 1
購買 10 本《設計模式》價格: 590 元

您好,尊敬的用戶 Tom
您的等級: VIP
您的折扣: 0.8
購買 10 本《設計模式》價格: 472 元

您好,尊敬的用戶 Tom
您的等級: Internal
您的折扣: 0.7
購買 10 本《設計模式》價格: 413 元
*/

現代 PHP OOP 進階特性(PHP 8.0+)

1. 唯讀屬性

class Config {
    public function __construct(
        public readonly string $appName,
        public readonly string $version,
        public readonly array $modules = []
    ) {}
}
$config = new Config('MyApp', '1.0.0');
// $config->appName = 'Other'; // Error: Cannot modify readonly property

2. 建構子屬性提升


// 簡潔替代傳統寫法
class Point {
    public function __construct(
        public float $x = 0.0,
        public float $y = 0.0,
        public float $z = 0.0
    ) {}
}
$p = new Point(1.5, 2.5);

3. 晚期靜態綁定 (LSB)

class Model {
    public static function tableName(): string {
        return static::TABLE; // 解析為子類常數
    }
}

class User extends Model {
    public const TABLE = 'users';
}

class Order extends Model {
    public const TABLE = 'orders';
}

echo User::tableName();  // users
echo Order::tableName(); // orders

4. Enum 枚舉類型 (PHP 8.1+)

enum OrderStatus: string {
    case Pending = 'pending';
    case Paid = 'paid';
    case Shipped = 'shipped';
    case Cancelled = 'cancelled';
    
    public function label(): string {
        return match($this) {
            self::Pending => '待付款',
            self::Paid => '已付款',
            self::Shipped => '已發貨',
            self::Cancelled => '已取消',
        };
    }
}

$status = OrderStatus::Paid;
echo $status->value;  // paid
echo $status->label(); // 已付款

設計原則與最佳實踐

  1. 單一職責原則 (SRP):類只負責一項功能(如 User 只管用戶屬性,結算交給 Service)
  2. 開閉原則 (OCP):對擴展開放,對修改關閉(新增用戶類型不修改 ProductSettle)
  3. 里氏替換原則 (LSP):子類必須能替換父類(所有 User 實現相同介面)
  4. 介面隔離原則 (ISP):介面細粒度,避免強制實現不需要的方法
  5. 依賴倒置原則 (DIP):依賴抽象(介面)而非具體類(ProductSettle 依賴 UserInterface)

總結

PHP OOP 從 PHP 5 起完善,現代版本(7.4/8.x)引入型別系統、屬性提升、唯讀屬性、Enum 等特性,已具備企業級開發能力。掌握 介面定義契約、抽象類提供共用實現、組合優於繼承、依賴注入解耦,是寫出可維護、可測試、可擴展 PHP 代碼的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved