ZetCode

PHP PDOStatement::fetchObject 方法

最后修改于 2025 年 4 月 19 日

PDOStatement::fetchObject 方法将结果集中的下一行获取为指定类的对象。它提供了一种面向对象的方式来访问数据库记录。

基本定义

PDOStatement::fetchObject 将结果集中的下一行作为对象检索。它可以创建具有映射到列名的属性的指定类的实例。

语法:public PDOStatement::fetchObject(string $class = "stdClass", array $constructorArgs = []): object|false。第一个参数是类名,默认为 stdClass。

基本的 fetchObject 用法

这展示了使用默认的 stdClass 来使用 fetchObject 的最简单方法。

fetch_object_basic.php
<?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 对象获取。列名成为对象的属性。可以使用对象运算符(->)访问属性。

获取到自定义类

这演示了直接将数据获取到自定义类的实例中。

fetch_object_custom_class.php
<?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 对象。该类必须具有与列名匹配的属性。类的所有方法都可以使用。

带有构造函数参数

这展示了在获取时如何将参数传递给类构造函数。

fetch_object_constructor_args.php
<?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 来处理多行。

fetch_object_multiple_rows.php
<?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 与预处理语句结合使用,以实现安全查询。

fetch_object_prepared.php
<?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 数据库值。

fetch_object_null_values.php
<?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。

高级类填充

这演示了使用私有属性进行的更复杂的对象填充。

fetch_object_advanced_hydration.php
<?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。

最佳实践

来源

PHP fetchObject 文档

本教程涵盖了 PDOStatement::fetchObject 方法,并提供了实用的示例,展示了不同的用法场景和最佳实践。

作者

我叫 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在教授编程方面有超过十年的经验。

列出 所有 PHP PDO 函数