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

PHP PDO 完整入門:資料庫抽象層、預處理語句、事務與錯誤處理實戰

     編輯:PHP 相關知識

PDO (PHP Data Objects) 是 PHP 5.1+ 內建的資料庫存取抽象層,支援 12+ 資料庫驅動,提供統一介面、預處理語句防 SQL 注入、事務控制與例外處理。本文從安裝到進階用法完整說明。

安裝與啟用

; php.ini
extension=pdo
extension=pdo_mysql      ; MySQL
extension=pdo_pgsql      ; PostgreSQL
extension=pdo_sqlite     ; SQLite
extension=pdo_oci        ; Oracle
extension=pdo_sqlsrv     ; SQL Server (Windows)
; 重啟 PHP-FPM / Apache

建立連線 (DSN)

<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'root';
$pass = 'secret';

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, // 拋出例外
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,       // 預設關聯陣列
    PDO::ATTR_EMULATE_PREPARES   => false,                  // 使用原生預處理
    PDO::ATTR_PERSISTENT         => true,                   // 長連線(視負載決定)
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",    // 設定編碼
];

try {
    $pdo = new PDO($dsn, $user, $pass, $options);
} catch (PDOException $e) {
    error_log('DB Connection Failed: ' . $e->getMessage());
    die('資料庫連線失敗');
}
?>

核心操作

查詢 (SELECT)

<?php
// 單筆
$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
$stmt->execute([$id]);
$user = $stmt->fetch(); // FETCH_ASSOC

// 多筆
$stmt = $pdo->query('SELECT * FROM articles WHERE status = 1 ORDER BY created_at DESC');
$articles = $stmt->fetchAll();

// 逐行處理大量資料(節省記憶體)
$stmt = $pdo->query('SELECT * FROM logs');
while ($row = $stmt->fetch()) {
    processLog($row);
}
?>

新增/修改/刪除 (INSERT/UPDATE/DELETE)

<?php
// 新增
$stmt = $pdo->prepare('INSERT INTO users (email, name) VALUES (?, ?)');
$stmt->execute([$email, $name]);
$newId = $pdo->lastInsertId();

// 批次新增(單一事務)
$pdo->beginTransaction();
try {
    $stmt = $pdo->prepare('INSERT INTO logs (msg) VALUES (?)');
    foreach ($messages as $msg) {
        $stmt->execute([$msg]);
    }
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}
?>

事務控制

<?php
$pdo->beginTransaction();
try {
    $pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
    $pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e;
}
?>

常用方法速查

方法用途回傳
query()執行 SELECT 等有結果集的 SQLPDOStatement
exec()執行 INSERT/UPDATE/DDL 等無結果集 SQL受影響行數 (int)
prepare()準備預處理語句PDOStatement
lastInsertId()取得最後自增 IDstring|int
beginTransaction()啟動事務bool
commit()提交事務bool
rollBack()回滾事務bool
setAttribute()設定屬性 (錯誤模式、預設取回模式等)bool
errorCode() / errorInfo()取得錯誤代碼/資訊string/array

PDOStatement 取回模式

<?php
$stmt = $pdo->query('SELECT id, name FROM users');
$stmt->setFetchMode(PDO::FETCH_CLASS, 'UserEntity'); // 映射到類別
$stmt->setFetchMode(PDO::FETCH_FUNC, function($id, $name) { return "$id:$name"; }); // 自訂函數
$stmt->setFetchMode(PDO::FETCH_KEY_PAIR); // [id => name, ...]
$stmt->setFetchMode(PDO::FETCH_GROUP);  // 依第一欄分組
?>

錯誤處理最佳實務

  • **統一設定 ERRMODE_EXCEPTION**,所有錯誤拋 PDOException,統一在入口捕獲記錄。
  • **生產環境關閉詳細錯誤顯示**,僅記錄 Log。
  • **連線失敗重試**(指數退避)針對暫時性網路故障。

進階:參數綁定型別

<?php
$stmt = $pdo->prepare('SELECT * FROM products WHERE price > :price AND status = :status');
$stmt->bindValue(':price', 100.50, PDO::PARAM_STR); // 價格用 STR 避免浮點精度問題
$stmt->bindValue(':status', 1, PDO::PARAM_INT);
$stmt->execute();
?>

PDO 是現代 PHP 資料庫開發的標準,掌握預處理、事務、錯誤模式,即可寫出安全、可維護、可移植的資料存取層。

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