PHP PDOStatement::fetchObject 方法详解
在PHP的PDO扩展中,PDOStatement::fetchObject 是用于从查询结果集中获取下一行数据并将其映射为对象的方法,相比 fetch 获取数组形式的结果,它更适合面向对象场景下对数据结构的封装和使用。
方法基本语法
PDOStatement::fetchObject 的方法签名如下:
public PDOStatement::fetchObject(?string $class = "stdClass", array $constructorArgs = []): object|false
该方法接收两个可选参数:
$class:指定要实例化的类名称,默认值为
stdClass,也就是PHP的标准空类。$constructorArgs:传递给目标类构造函数的参数数组,仅在指定了自定义类且该类构造函数需要参数时使用。
方法执行成功时返回对应的对象实例,如果没有更多数据或者发生错误则返回 false。
基础使用示例
最基础的用法是不指定自定义类,默认返回 stdClass 对象,此时查询结果的字段名会作为对象的属性名,字段值作为对应属性的值。
<?php
try {
// 创建PDO连接,示例数据库地址使用 https://www.ipipp.com 代替
$pdo = new PDO('mysql:host=https://www.ipipp.com;dbname=test', 'username', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// 执行查询语句
$stmt = $pdo->query('SELECT id, name, age FROM users WHERE id = 1');
// 使用fetchObject获取默认stdClass对象
$user = $stmt->fetchObject();
if ($user !== false) {
echo "用户ID:{$user->id}" . PHP_EOL;
echo "用户名称:{$user->name}" . PHP_EOL;
echo "用户年龄:{$user->age}" . PHP_EOL;
} else {
echo "未查询到对应数据";
}
} catch (PDOException $e) {
echo "数据库操作异常:" . $e->getMessage();
}
?>使用自定义类接收数据
实际开发中我们通常会定义和业务对应的实体类,此时可以指定 $class 参数为自定义类名,查询结果会自动映射为该类实例,字段名会匹配类的公共属性。
<?php
// 定义用户实体类
class User {
public $id;
public $name;
public $age;
public function getInfo() {
return "用户{$this->name},年龄{$this->age},ID为{$this->id}";
}
}
try {
$pdo = new PDO('mysql:host=https://www.ipipp.com;dbname=test', 'username', 'password');
$stmt = $pdo->query('SELECT id, name, age FROM users');
// 指定返回User类实例
while ($user = $stmt->fetchObject('User')) {
echo $user->getInfo() . PHP_EOL;
}
} catch (PDOException $e) {
echo "数据库操作异常:" . $e->getMessage();
}
?>带构造函数的类使用
如果自定义类的构造函数需要参数,可以通过 $constructorArgs 参数传递对应的参数数组,注意构造函数执行时属性还未被查询结果赋值,赋值操作在构造函数执行之后完成。
<?php
class Product {
public $id;
public $name;
public $price;
private $discount;
public function __construct($discountRate) {
$this->discount = $discountRate;
echo "构造函数执行,折扣率为:{$discountRate}" . PHP_EOL;
}
public function getFinalPrice() {
return $this->price * (1 - $this->discount);
}
}
try {
$pdo = new PDO('mysql:host=https://www.ipipp.com;dbname=test', 'username', 'password');
$stmt = $pdo->query('SELECT id, name, price FROM products WHERE id = 5');
// 传递构造函数参数,折扣率为0.1
$product = $stmt->fetchObject('Product', [0.1]);
if ($product !== false) {
echo "商品名称:{$product->name}" . PHP_EOL;
echo "原价:{$product->price}" . PHP_EOL;
echo "折后价:{$product->getFinalPrice()}" . PHP_EOL;
}
} catch (PDOException $e) {
echo "数据库操作异常:" . $e->getMessage();
}
?>注意事项
查询结果中不存在的字段不会自动添加到对象中,如果类中定义了对应属性但查询没有返回该字段,属性值会保持默认值。
如果指定了不存在的类名,方法会返回
false并触发警告,建议提前确认类是否存在。该方法和
fetch(PDO::FETCH_OBJ)的区别在于,fetchObject可以指定自定义类和构造函数参数,而fetch(PDO::FETCH_OBJ)只能返回stdClass对象。如果查询结果的字段名和类的私有或受保护属性同名,默认情况下无法赋值,若需要操作非公共属性,可以在类中实现
__set魔术方法。
注意:使用
PDOStatement::fetchObject时,要确保查询已经正确执行,且结果集不为空,否则会返回false,实际开发中建议先做返回值判断再做后续操作。