系統整理 PHP Data Objects (PDO) 核心架構:抽象介面層、三大預定義類別、資料庫驅動啟用、參數綁定與預編譯優勢、交易處理範例、效能基準與適用場景分析。
pdo_mysql, pdo_pgsql, pdo_sqlite 等)使用。php.ini 取消註解 extension=php_pdo.dll 及對應驅動。| 類別 | 職責 | 關鍵方法 |
|---|---|---|
| PDO | 資料庫連線代表 | prepare(), query(), exec(), beginTransaction(), commit(), rollBack(), lastInsertId() |
| PDOStatement | 預處理語句與結果集 | execute(), fetch(), fetchAll(), bindParam(), bindValue(), rowCount() |
| PDOException | 例外處理 | getMessage(), getCode() |
<?php
try {
$pdo = new PDO("mysql:host=localhost;dbname=photo;charset=utf8", "root", "123456");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
die("連線失敗: " . $e->getMessage());
}
// 查詢
$stmt = $pdo->query("SELECT * FROM users WHERE status = 1");
$users = $stmt->fetchAll();
// 新增(預處理 + 參數綁定)
$stmt = $pdo->prepare("INSERT INTO users (username, email, password) VALUES (?, ?, ?)");
$stmt->execute(['john', 'john@example.com', password_hash('secret', PASSWORD_DEFAULT)]);
$newId = $pdo->lastInsertId();
?>
<?php
try {
$pdo->beginTransaction();
$amt = 250;
$pdo->exec("UPDATE users SET money = money - $amt WHERE id = 1");
$pdo->exec("UPDATE users SET money = money + $amt WHERE id = 2");
// 故意拼錯欄位名模擬失敗:money → monet
$pdo->exec("UPDATE users SET monet = money - $amt WHERE id = 3");
$pdo->commit();
echo "轉帳成功";
} catch (Exception $e) {
$pdo->rollBack();
echo "轉帳失敗: " . $e->getMessage();
}
?>
交易四大特性 (ACID):原子性、一致性、隔離性、持久性。需資料表引擎為 InnoDB。
bindParam() 參考綁定 vs bindValue() 值綁定,前者適合迴圈重複執行。| 指標 | PDO | mysqli (原生) | 說明 |
|---|---|---|---|
| CRUD 效能 | 較低 5-15% | 基準 | 抽象層額外開銷 |
| 長連線負載 | 較高且穩定 | 較低 | PDO 連線池管理較好 |
| 記憶體使用 | 略高 | 較低 | 物件封裝開銷 |
ERRMODE_EXCEPTION,統一用 try-catch 處理錯誤。:name 提升 SQL 可讀性。掌握 PDO 核心 API 與最佳實務,能編寫安全、可維護、跨資料庫相容的資料存取層。