在日常開發中,我們經常會遇到需要分頁查詢數據庫並將結果以對象形式返回的需求。 PHP 的PDO 擴展為此提供了非常便利的方式,其中PDOStatement::fetchObject方法尤其適合直接將查詢結果映射為對象。
本文將通過示例演示,如何結合fetchObject實現分頁查詢,並正確地處理對像數據。
首先,確保你的環境中已經開啟了PDO 擴展,並連接了數據庫。例如:
<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$username = 'dbuser';
$password = 'dbpass';
try {
$pdo = new PDO($dsn, $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
die('數據庫連接失敗: ' . $e->getMessage());
}
?>
為了分頁,我們需要設置LIMIT和OFFSET 。假設我們要查詢一個users表的數據,每頁顯示5 條記錄。
<?php
$page = isset($_GET['page']) ? (int)$_GET['page'] : 1;
$page = max($page, 1); // 最小為第1頁
$pageSize = 5;
$offset = ($page - 1) * $pageSize;
$sql = 'SELECT id, username, email FROM users ORDER BY id ASC LIMIT :limit OFFSET :offset';
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':limit', $pageSize, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
?>
接下來,我們通過fetchObject方法,一行一行地將結果映射為對象。可以自定義一個類,也可以直接用PHP 內置的stdClass 。
示例使用stdClass :
<?php
$users = [];
while ($user = $stmt->fetchObject()) {
$users[] = $user;
}
// 打印對像數組
foreach ($users as $user) {
echo 'ID: ' . $user->id . '<br>';
echo '使用者名稱: ' . htmlspecialchars($user->username, ENT_QUOTES, 'UTF-8') . '<br>';
echo '郵箱: ' . htmlspecialchars($user->email, ENT_QUOTES, 'UTF-8') . '<br><br>';
}
?>
如果你希望使用自定義的用戶類,可以這樣定義並傳入:
<?php
class User
{
public $id;
public $username;
public $email;
public function getProfileUrl()
{
return 'https://gitbox.net/user/profile.php?id=' . urlencode($this->id);
}
}
$users = [];
while ($user = $stmt->fetchObject(User::class)) {
$users[] = $user;
}
// 打印對像數組
foreach ($users as $user) {
echo 'ID: ' . $user->id . '<br>';
echo '使用者名稱: ' . htmlspecialchars($user->username, ENT_QUOTES, 'UTF-8') . '<br>';
echo '郵箱: ' . htmlspecialchars($user->email, ENT_QUOTES, 'UTF-8') . '<br>';
echo '個人資料鏈接: <a href="' . htmlspecialchars($user->getProfileUrl(), ENT_QUOTES, 'UTF-8') . '">查看</a><br><br>';
}
?>
注意, fetchObject方法可以直接實例化你指定的類,並且自動給屬性賦值,非常適合需要封裝行為的方法,比如上面的getProfileUrl 。
使用PDOStatement::fetchObject可以非常優雅地將數據庫記錄映射為對象,特別適合對象導向的應用開發。結合分頁查詢時,只需要在SQL 語句中加上LIMIT和OFFSET ,然後逐條用fetchObject獲取即可。
如果你正在構建一個MVC 框架或者後台管理系統,這種方式會讓你的代碼更加簡潔和可維護。