棄用:mysql_*(PHP 7.0 移除)、mysql_connect、mysql_query 等古老函數。
| 分類 | 方法/屬性 | 用途 | 關鍵參數/返回值 |
|---|---|---|---|
| 連接 | new PDO($dsn, $user, $pass, $options) | 建立連接 | DSN: mysql:host=...;dbname=...;charset=utf8mb4 |
setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION) | 異常模式(必開) | 拋出 PDOException | |
setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC) | 默認獲取模式 | FETCH_ASSOC/NUM/BOTH/OBJ/CLASS | |
setAttribute(PDO::ATTR_EMULATE_PREPARES, false) | 真實預處理 | 防注入核心,關閉模擬 | |
| 預處理執行 | prepare($sql) | 創建預處理語句 | 返回 PDOStatement |
execute($params = []) | 綁定參數並執行 | 數組綁定:[':name' => $val] 或 [$val1, $val2] | |
bindParam($param, &$var, $type) | 引用綁定(循環優勢) | 類型:PARAM_STR/INT/BOOL/NULL/LOB | |
bindValue($param, $value, $type) | 值綁定 | 立即求值 | |
rowCount() | 影響行數(INSERT/UPDATE/DELETE) | SELECT 不可靠,勿用於判斷結果集 | |
| 結果集獲取 | fetch($mode = FETCH_ASSOC) | 單行獲取 | 返回數組/對象/false |
fetchAll($mode) | 全量獲取 | 大結果集慎用,記憶體風險 | |
fetchColumn($col = 0) | 單列值 | 聚合查詢常用 | |
fetchObject($class = 'stdClass') | 映射對象 | 支持自定義類構造函數 | |
setFetchMode(PDO::FETCH_CLASS, 'User') | 設置映射類 | 屬性自動映射 | |
getColumnMeta($index) | 列元數據 | 名稱、類型、長度、標志 | |
| 事務控制 | beginTransaction() | 開啟事務 | 需 InnoDB,DDL 會隱式提交 |
commit() | 提交 | ||
rollBack() | 回滾 | ||
| 屬性/信息 | lastInsertId($seq = null) | 自增 ID | PostgreSQL 需指定序列名 |
errorCode() / errorInfo() | 錯誤代碼/詳情 | 非異常模式下使用 | |
getAttribute(PDO::ATTR_CONNECTION_STATUS) | 連接狀態 | 長連接心跳檢查 |
| 操作 | mysqli 方法 | PDO 對應 |
|---|---|---|
| 連接 | new mysqli($host, $user, $pass, $db, $port) | new PDO(...) |
| 字符集 | set_charset('utf8mb4') | DSN charset=utf8mb4 |
| 預處理 | prepare($sql) → bind_param('ssi', ...) → execute() | prepare() → execute([...]) |
| 查詢 | query($sql) 返回 mysqli_result | query($sql) 返回 PDOStatement |
| 遍歷結果 | fetch_assoc() / fetch_array() / fetch_object() | fetch(PDO::FETCH_ASSOC) 等 |
| 釋放結果 | free() | null / 變量銷毀 |
| 事務 | begin_transaction() / commit() / rollback() | 同名方法 |
| 自增 ID | insert_id | lastInsertId() |
| 影響行數 | affected_rows | rowCount() |
| 錯誤 | errno / error | errorCode() / errorInfo() |
| 關閉 | close() | $pdo = null |
// 1. 安全配置模板
$pdo = new PDO(
'mysql:host=127.0.0.1;dbname=test;charset=utf8mb4',
'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",
]
);
// 2. 批量插入(單條預處理循環 vs 多值語句)
// 方案 A: 預處理循環(事務包裹,穩健)
$pdo->beginTransaction();
$stmt = $pdo->prepare("INSERT INTO logs (level, message) VALUES (?, ?)");
foreach ($logs as $log) {
$stmt->execute([$log['level'], $log['message']]);
}
$pdo->commit();
// 方案 B: 多值語句(性能極致,需注意 max_allowed_packet)
$values = []; $params = [];
foreach ($logs as $log) {
$values[] = '(?, ?)';
$params[] = $log['level'];
$params[] = $log['message'];
}
$pdo->execute("INSERT INTO logs (level, message) VALUES " . implode(',', $values), $params);
// 3. 分頁查詢(游標優化大偏移)
$stmt = $pdo->prepare("SELECT * FROM posts WHERE id > ? ORDER BY id LIMIT ?");
$stmt->execute([$lastSeenId, $pageSize]);
// 4. 僅獲取首行首列(聚合/計數)
$count = $pdo->query("SELECT COUNT(*) FROM users")->fetchColumn();
// 5. 映射到領域對象
class User { public $id; public $name; public $email; }
$stmt = $pdo->query("SELECT id, username AS name, email FROM users");
$stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
$users = $stmt->fetchAll(); // User[] 對象數組
// 6. 異常處理統一入口
try {
// DB 操作
} catch (PDOException $e) {
error_log(sprintf('[%s] SQLSTATE[%s] %s', date('c'), $e->getCode(), $e->getMessage()));
// 業務層轉換為統一異常或返回錯誤碼
}
CHARSET utf8mb4 COLLATE utf8mb4_general_cicharset=utf8mb4SET NAMES utf8mb4(PDO MYSQL_ATTR_INIT_COMMAND 自動執行)header('Content-Type: text/html; charset=utf-8') 或 <meta charset="utf-8">PHP 操作 MySQL 的**專業標準**是:**PDO + 真實預處理 + 異常模式 + utf8mb4 全鏈路 + 單例連接 + 統一異常處理**。本文提供的 API 速查表與代碼片段覆蓋 95% 日常開發場景。建議將 Database 類封裝為項目基礎設施,禁止在業務代碼中直接裸露 PDO 操作,**Repository 模式**封裝 SQL 細節,才是可維護架構的起點。