在日常开发中,我们经常会遇到需要分页查询数据库并将结果以对象形式返回的需求。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 框架或者后台管理系统,这种方式会让你的代码更加简洁和可维护。