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

PHP PDO 核心特性與 API 快速參考指南

     編輯:PHP 相關知識

前言

PDO (PHP Data Objects) 提供統一資料庫存取介面,支援 12+ 資料庫驅動。本文彙整核心特性、常用 API、預處理語句、事務處理、錯誤模式等實戰重點。

一、核心特性

  • 輕量級 C 擴充套件:效能優於舊式 mysql_* 函數。
  • 資料庫無關介面:同一套 API 切換 MySQL/PostgreSQL/SQLite/Oracle/SQL Server 等。
  • 預處理語句:防 SQL 注入、提升重複執行效能。
  • 事務支援:beginTransaction()/commit()/rollBack()。
  • 大物件 (LOB) 處理:資料流讀寫 BLOB/CLOB。
  • 游標捲動:PDO::CURSOR_SCROLL 支援前向/後向/隨機存取。
  • 錯誤模式靈活:Silent/Warning/Exception 三種模式。
  • SQLSTATE 錯誤代碼:標準化跨資料庫錯誤識別。

二、連線建立 (DSN)

<?php
// MySQL
$dsn = 'mysql:host=127.0.0.1;port=3306;dbname=test;charset=utf8mb4';
$pdo = new PDO($dsn, 'user', 'pass', [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, // 推薦:拋出異常
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES => false, // 使用原生預處理
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4",
]);

// PostgreSQL
$dsn = 'pgsql:host=localhost;port=5432;dbname=test';

// SQLite
$dsn = 'sqlite:/path/to/database.db';

// SQL Server (sqlsrv 驅動)
$dsn = 'sqlsrv:Server=localhost;Database=test';

三、常用 API 快速查表

方法用途回傳值
query($sql)執行 SELECT,回傳 PDOStatementPDOStatement|false
exec($sql)執行 INSERT/UPDATE/DELETE/DDL影響行數|false
prepare($sql)預處理語句PDOStatement
lastInsertId($seq)取得自增 IDstring|false
beginTransaction()啟動事務bool
commit()提交事務bool
rollBack()回滾事務bool
inTransaction()檢查是否在事務中bool
setAttribute()設定屬性bool
getAttribute()取得屬性mixed
errorCode()取得 SQLSTATEstring
errorInfo()取得詳細錯誤資訊array

四、PDOStatement 核心方法

方法說明
execute($params)執行預處理,$params 為陣列綁定參數
bindParam($param, $var, $type)參數繫結變數參考
bindValue($param, $value, $type)參數繫結值
fetch($mode)取得單行
fetchAll($mode)取得所有行
fetchColumn($col)取得單欄值
rowCount()影響行數 (僅 INSERT/UPDATE/DELETE 可靠)
closeCursor()釋放結果集
setFetchMode($mode)設定預設取得模式
getColumnMeta($col)取得欄位中繼資料

五、實戰範例:預處理 + 事務 + 異常處理

<?php
try {
    $pdo->beginTransaction();

    // 1. 新增訂單
    $stmt = $pdo->prepare('INSERT INTO orders (user_id, total, status) VALUES (?, ?, ?)');
    $stmt->execute([$userId, $total, 'pending']);
    $orderId = $pdo->lastInsertId();

    // 2. 批次新增明細
    $stmtDetail = $pdo->prepare('INSERT INTO order_items (order_id, product_id, qty, price) VALUES (?, ?, ?, ?)');
    foreach ($items as $item) {
        $stmtDetail->execute([$orderId, $item['product_id'], $item['qty'], $item['price']]);
    }

    // 3. 扣減庫存 (樂觀鎖)
    $stmtStock = $pdo->prepare('UPDATE products SET stock = stock - ? WHERE id = ? AND stock >= ?');
    foreach ($items as $item) {
        $stmtStock->execute([$item['qty'], $item['product_id'], $item['qty']]);
        if ($stmtStock->rowCount() === 0) {
            throw new \Exception("Product {$item['product_id']} stock insufficient");
        }
    }

    $pdo->commit();
    echo "Order $orderId created successfully.";
} catch (\Throwable $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    error_log("Order create failed: " . $e->getMessage());
    echo "Operation failed: " . $e->getMessage();
}

六、錯誤處理模式對比

模式設定行為推薦場景
ExceptionPDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION拋出 PDOException現代應用、統一 try-catch
WarningPDO::ERRMODE_WARNING觸發 E_WARNING快速除錯、舊專案相容
SilentPDO::ERRMODE_SILENT (預設)不報錯,需手動檢查 errorCode/errorInfo極少用,不推薦

七、進階技巧

  • 命名參數::name 而非 ?,可重複使用、順序無關。
  • PDO::FETCH_CLASS:直接映射至實體類別 $stmt->fetchAll(PDO::FETCH_CLASS, User::class)。
  • 批次插入優化:單一 execute 多組值 INSERT INTO t (a,b) VALUES (?,?), (?,?), ... (支援驅動依賴)。
  • 連線池:PHP 無內建連線池,配合 PHP-FPM 持久連線 PDO::ATTR_PERSISTENT => true (慎用,可能耗盡資料庫連線)。

八、官方文件

PHP.net PDO 手冊

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