在使用PHP 進行數據庫開發時,PDO(PHP Data Objects)是一種非常受歡迎的數據庫訪問方式,它提供了統一的接口來操作各種數據庫。本文將探討兩個常用的PDO 方法: PDOStatement::fetchAll和PDOStatement::rowCount ,並分析如何在實際開發中結合使用它們,以提升查詢效率和代碼的健壯性。
在使用PDO 執行SELECT 查詢時,我們通常會使用fetchAll來獲取所有的結果行。這是一個非常直接的方式,可以將查詢結果以數組的形式返回,便於遍歷處理。
$stmt = $pdo->query("SELECT * FROM users");
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
另一方面, rowCount的作用是返回受上一條SQL 語句影響的行數。在執行SELECT語句時, rowCount的行為依賴於數據庫驅動。在某些驅動中(如MySQL 的PDO_MYSQL),對SELECT查詢調用rowCount並不能總是返回準確的行數。
$count = $stmt->rowCount();
很多開發者在判斷查詢結果是否為空時,會習慣性地寫下這樣的代碼:
$stmt = $pdo->query("SELECT * FROM users WHERE status = 'active'");
if ($stmt->rowCount() > 0) {
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
這種做法在某些數據庫驅動下(尤其是MySQL)並不會返回預期的結果。原因是:對於SELECT 語句,PDO 的rowCount 在某些驅動中返回的是“0”,即使結果實際是非空的。
為了獲得可靠的結果並提升效率,推薦使用fetchAll獲取所有數據後,再通過count來判斷是否有數據:
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = :status");
$stmt->execute(['status' => 'active']);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($users) > 0) {
// 有數據,處理邏輯
} else {
// 無數據提示
}
這種方式的優勢在於:
避免了rowCount在不同驅動下表現不一致的問題;
fetchAll執行後數據已經加載到內存, count($users)操作開銷極小;
可讀性更強,邏輯更明確。
雖然fetchAll很方便,但在處理大量數據時,它可能會消耗大量內存。此時可以考慮以下策略:
$stmt = $pdo->prepare("SELECT * FROM logs WHERE created_at > :date");
$stmt->execute(['date' => '2025-01-01']);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
// 實時處理每一行數據
}
這種方式適用於結果集很大、但不需要一次性加載的場景。
在只需獲取部分數據的情況下,添加LIMIT 是提高效率的重要方式:
$stmt = $pdo->prepare("SELECT * FROM users WHERE status = :status LIMIT 100");
$stmt->execute(['status' => 'active']);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
如果你只想知道是否有數據,而不需要實際獲取結果,可以使用SELECT COUNT(*) :
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE status = :status");
$stmt->execute(['status' => 'active']);
$count = $stmt->fetchColumn();
if ($count > 0) {
// 有匹配的數據
}
假設你在gitbox.net的後台系統中需要列出所有已激活用戶列表:
$url = 'https://gitbox.net/api/active-users';
$stmt = $pdo->prepare("SELECT id, username, email FROM users WHERE status = :status ORDER BY created_at DESC LIMIT 50");
$stmt->execute(['status' => 'active']);
$users = $stmt->fetchAll(PDO::FETCH_ASSOC);
if (count($users) > 0) {
foreach ($users as $user) {
echo "使用者名稱:{$user['username']},郵箱:{$user['email']}<br>";
}
} else {
echo "沒有找到已激活的用戶。";
}
避免在SELECT 查詢中依賴rowCount判斷結果行數;
建議使用fetchAll加count的方式判斷數據是否存在;
對於大數據量查詢,使用fetch迭代和LIMIT是關鍵優化手段;
若僅需統計行數,可使用SELECT COUNT(*)提高效率。
合理使用PDO 提供的方法,不僅能提高系統性能,還能避免在跨數據庫開發中出現不一致行為,提升代碼的健壯性和可維護性。