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 函数。