PHP PDOStatement::fetchObject 方法
最后修改于 2025 年 4 月 19 日
PDOStatement::fetchObject 方法将结果集中的下一行获取为指定类的对象。它提供了一种面向对象的方式来访问数据库记录。
基本定义
PDOStatement::fetchObject 将结果集中的下一行作为对象检索。它可以创建具有映射到列名的属性的指定类的实例。
语法:public PDOStatement::fetchObject(string $class = "stdClass", array $constructorArgs = []): object|false。第一个参数是类名,默认为 stdClass。
基本的 fetchObject 用法
这展示了使用默认的 stdClass 来使用 fetchObject 的最简单方法。
<?php
declare(strict_types=1);
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT id, name, email FROM users LIMIT 1');
$user = $stmt->fetchObject();
echo "User: {$user->name} ({$user->email})";
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这会将单行作为 stdClass 对象获取。列名成为对象的属性。可以使用对象运算符(->)访问属性。
获取到自定义类
这演示了直接将数据获取到自定义类的实例中。
<?php
declare(strict_types=1);
class User {
public int $id;
public string $name;
public string $email;
public function getInfo(): string {
return "{$this->name} <{$this->email}>";
}
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT id, name, email FROM users LIMIT 1');
$user = $stmt->fetchObject('User');
echo $user->getInfo();
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这会创建一个具有数据库行数据的 User 对象。该类必须具有与列名匹配的属性。类的所有方法都可以使用。
带有构造函数参数
这展示了在获取时如何将参数传递给类构造函数。
<?php
declare(strict_types=1);
class UserProfile {
public function __construct(
public int $id,
public string $name,
public string $role = 'user'
) {}
public function display(): string {
return "{$this->name} ({$this->role})";
}
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT id, name FROM users LIMIT 1');
$user = $stmt->fetchObject('UserProfile', ['admin']);
echo $user->display();
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这会将 'admin' 作为 role 参数传递给构造函数。数据库列映射到其余的构造函数参数。属性将被提升。
获取多行
这演示了在循环中使用 fetchObject 来处理多行。
<?php
declare(strict_types=1);
class Product {
public int $id;
public string $name;
public float $price;
public function formatPrice(): string {
return '$' . number_format($this->price, 2);
}
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT id, name, price FROM products');
while ($product = $stmt->fetchObject('Product')) {
echo "{$product->name}: {$product->formatPrice()}\n";
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这会循环遍历所有产品,为每一行创建一个 Product 对象。formatPrice 方法以一致的格式化所有产品的价格。
带有预准备语句
这会将 fetchObject 与预处理语句结合使用,以实现安全查询。
<?php
declare(strict_types=1);
class Customer {
public int $id;
public string $name;
public string $email;
public DateTime $created_at;
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->prepare('SELECT id, name, email, created_at FROM customers WHERE id = ?');
$stmt->execute([42]);
$customer = $stmt->fetchObject('Customer');
if ($customer) {
$date = $customer->created_at->format('Y-m-d');
echo "Customer {$customer->name} joined on {$date}";
}
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这会使用预处理语句安全地按 ID 获取客户。created_at 列会自动转换为 DateTime 对象。
处理 NULL 值
这展示了 fetchObject 如何在对象中处理 NULL 数据库值。
<?php
declare(strict_types=1);
class Employee {
public ?int $manager_id = null;
public string $name;
public ?string $department = null;
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT name, manager_id, department FROM employees LIMIT 1');
$employee = $stmt->fetchObject('Employee');
$managerText = $employee->manager_id ? "Manager ID: {$employee->manager_id}" : "No manager";
echo "{$employee->name}, {$managerText}";
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这通过使用可空类型来正确处理 NULL 数据库值。如果数据库值为 NULL,则属性将初始化为 NULL。
高级类填充
这演示了使用私有属性进行的更复杂的对象填充。
<?php
declare(strict_types=1);
class Order {
private int $id;
private float $total;
private DateTimeImmutable $order_date;
public function getId(): int {
return $this->id;
}
public function getTotal(): float {
return $this->total;
}
public function getOrderDate(): DateTimeImmutable {
return $this->order_date;
}
public function getFormattedDate(): string {
return $this->order_date->format('M j, Y');
}
}
try {
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$stmt = $pdo->query('SELECT id, total, order_date FROM orders LIMIT 1');
$order = $stmt->fetchObject('Order');
echo "Order #{$order->getId()} on {$order->getFormattedDate()}";
echo "Total: $" . number_format($order->getTotal(), 2);
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
这会使用私有属性填充 Order 对象。该类提供了 getter 方法来访问数据。order_date 会被转换为 DateTimeImmutable。
最佳实践
- 类型安全:使用与数据库列匹配的属性类型。
- 错误处理:始终检查 fetchObject 是否返回 false。
- 性能:对于小型结果集,请考虑使用 fetchAll。
- 安全:与预处理语句结合使用以处理用户输入。
- 填充:如有需要,请在类构造函数中添加验证。
来源
本教程涵盖了 PDOStatement::fetchObject 方法,并提供了实用的示例,展示了不同的用法场景和最佳实践。
作者
列出 所有 PHP PDO 函数。