類別是物件導向程式設計的基石。本文透過一個 User 類別完整範例,詳細說明屬性宣告、方法定義、$this 指標、資料庫查詢封裝、輸入驗證等 PHP 類別核心語法與實務模式。
<?php
class User {
// 公開屬性 (不建議,破壞封裝)
public $u_uid; // 使用者帳號 (英文)
public $u_mbname; // 模板名稱
public $u_css; // 樣式表
public $u_documentbg; // 頁面背景
public $u_csstop; // 頂部背景
public $u_cssbottom; // 底部背景
public $u_realname; // 真實姓名 (中文)
public $u_id; // 資料表 ID
public $u_edu; // 學歷
public $u_work; // 工作
public $u_head; // 頭像
public $u_sitename; // 站點名稱
public $u_visited; // 瀏覽數
public $u_blog; // 部落格連結
public $host; // 主機資訊
// 建議:使用 private/protected + 存取器
// private $username;
// public function getUsername() { return $this->username; }
}
public function userinfo($id) {
// 1. 輸入驗證與清理
$id = $this->safe_function($id); // 假設有此方法防 SQL 注入
if (empty($id) || !is_numeric($id)) {
exit("");
}
// 2. 執行查詢 (使用舊 mysql 擴充,現代請改用 PDO/MySQLi)
$sql = "SELECT * FROM uidname WHERE u_id = '$id'";
$result = mysql_query($sql) or die("Error system busy.....plase wait!");
// 3. 檢查結果並填充屬性
if (mysql_num_rows($result)) {
$rs = mysql_fetch_object($result);
$this->u_id = $rs->id;
$this->u_uid = $rs->username;
$this->u_realname = $rs->realname;
$this->u_documentbg= $rs->documentbg;
$this->u_csstop = $rs->csstop;
$this->u_cssbottom = $rs->cssbottom;
$this->u_mbname = $rs->mbname;
$this->u_edu = $rs->edu;
$this->u_work = $rs->works;
$this->u_sitename = $rs->sitename;
$this->u_visited = $rs->visited;
$this->u_blog = $rs->u_id; // 疑似邏輯錯誤,應為 $rs->blog
} else {
header("location:blog/error.php");
exit;
}
}
// 輔助方法:簡單的輸入過濾 (示意用,實務請用預處理語句)
private function safe_function($input) {
return mysql_real_escape_string(trim($input));
}
}
<?php
require_once 'User.php';
$user = new User();
$user->userinfo(123); // 依 ID 載入使用者資料
echo "歡迎,{$user->u_realname} ({$user->u_uid})";
echo "部落格:{$user->u_blog}";
echo "學歷:{$user->u_edu}";
?>
<?php
declare(strict_types=1);
class User {
// 型別宣告的私有屬性
private int $id;
private string $username;
private string $realName;
private string $email;
private ?string $avatar = null;
private array $preferences = [];
// 依賴注入:資料庫連線不在類別內建立
public function __construct(private PDO $pdo) {}
// 靜態工廠方法:從 ID 載入
public static function findById(PDO $pdo, int $id): ?self {
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$row) return null;
$user = new self($pdo);
$user->hydrate($row);
return $user;
}
// 內部填充方法
private function hydrate(array $row): void {
$this->id = $row['id'];
$this->username = $row['username'];
$this->realName = $row['real_name'];
$this->email = $row['email'];
$this->avatar = $row['avatar'] ?? null;
$this->preferences = json_decode($row['preferences'] ?? '[]', true);
}
// 唯讀存取器
public function getId(): int { return $this->id; }
public function getUsername(): string { return $this->username; }
public function getRealName(): string { return $this->realName; }
public function getEmail(): string { return $this->email; }
public function getAvatar(): ?string { return $this->avatar; }
public function getPreferences(): array { return $this->preferences; }
// 受控修改器
public function setEmail(string $email): void {
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new InvalidArgumentException('無效 Email 格式');
}
$this->email = $email;
$this->save();
}
// 持久化
private function save(): void {
$stmt = $this->pdo->prepare('UPDATE users SET email = ? WHERE id = ?');
$stmt->execute([$this->email, $this->id]);
}
}
| 概念 | 舊範例 | 現代最佳實踐 |
|---|---|---|
| 屬性可見性 | public | private + getter/setter |
| 型別安全 | 無 | 嚴格型別宣告 (PHP 7.4+) |
| 資料庫存取 | mysql_* 函式 + 字串拼接 | PDO + 預處理語句 + 參數綁定 |
| 相依管理 | 類別內建立連線 | 依賴注入 (Constructor Injection) |
| 物件建立 | new User() -> userinfo() | 靜態工廠方法 findById() |
| 錯誤處理 | die()/exit() | 拋出例外 (Exception) |
理解 PHP 類別語法只是起點。真正的工程實踐在於:封裝內部狀態、使用型別系統、依賴抽象而非具體實作、錯誤以例外處理、資料存取分離。從傳統寫法遷移至現代模式,能讓程式碼更安全、可測試、可維護。