在使用 PHP 的 PDO(PHP Data Objects)操作数据库时,获取查询结果的方式多种多样,其中 PDOStatement::fetchObject() 和 PDOStatement::fetch()(配合 PDO::FETCH_NUM 实现类似“fetchRow”效果)是最常见的两种方式。但很多开发者经常疑惑:我到底该选哪一个?它们在性能、结构、使用便利性上有什么区别?本文将带你深入了解它们的异同和适用场景。
$pdo = new PDO("mysql:host=localhost;dbname=test", "user", "password");
$stmt = $pdo->query("SELECT id, name, email FROM users");
$user = $stmt->fetchObject();
echo $user->name;
返回值:返回一个对象,默认是 stdClass 的实例,也可以传入类名实例化为自定义类。
访问方式:属性方式($user->name)
可读性高,适合结构化访问数据。
虽然没有 fetchRow() 这个方法,fetch(PDO::FETCH_NUM) 可以视作其对应方式:
$stmt = $pdo->query("SELECT id, name, email FROM users");
$row = $stmt->fetch(PDO::FETCH_NUM);
echo $row[1]; // name
返回值:返回索引数组(每列是按数字键排列)
访问方式:索引方式($row[0], $row[1])
更适合数据结构已知且列顺序固定的情况。
对比项 | fetchObject() | fetch(PDO::FETCH_NUM) |
---|---|---|
返回类型 | 对象(默认 stdClass) | 数组(索引数组) |
属性访问 | $obj->property | $row[0] |
可扩展性 | 可传入类名,自动填充类属性 | 无法自动映射为类 |
性能 | 稍慢(创建对象) | 稍快(纯数组) |
可读性 | 较高 | 一般 |
推荐使用场景 | ORM、面向对象开发、清晰结构输出 | 简单报表输出、批量处理、临时处理数据 |
使用 fetchObject() 非常合适,它能将结果直接映射为对象,使得后续业务逻辑处理更加自然、清晰。
class User {
public $id;
public $name;
public $email;
}
$stmt = $pdo->query("SELECT id, name, email FROM users");
$user = $stmt->fetchObject("User");
echo $user->email;
适合场景:企业级项目、DDD 架构、RESTful 接口返回对象
使用 fetch(PDO::FETCH_NUM) 可以提升性能,避免不必要的对象创建,同时对字段顺序有明确控制。
while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
echo implode(",", $row) . PHP_EOL;
}
适合场景:批量处理、数据导出 CSV、快速报表系统
虽然 fetchObject() 提供了更高的可读性,但由于每条记录都会生成一个对象,它在处理大量数据时性能略逊于 fetch(PDO::FETCH_NUM)。以 10 万条数据为例:
fetchObject():大约耗时 1.5 秒
fetch(PDO::FETCH_NUM):大约耗时 1.1 秒
实测环境基于本地 MySQL 8.0 和 PHP 8.1,测试代码地址:https://gitbox.net/test/pdo_benchmark.php
如果你在构建 API、ORM 或类封装层,推荐使用 fetchObject()。
如果你处理的是临时性、结构明确的报表或批量数据,选择 fetch(PDO::FETCH_NUM) 更合适。
可读性优先时选对象,性能优先时选数组。
场景 | 推荐方法 |
---|---|
面向对象处理 | fetchObject() |
快速遍历、导出数据 | fetch(PDO::FETCH_NUM) |
需要结构清晰的数据封装 | fetchObject() |
数据量非常大、追求极限性能 | fetch(PDO::FETCH_NUM) |
总之,两者各有所长,合理使用,才能发挥 PDO 的最大效能。