ZetCode

PHP PDOStatement::fetch 方法

最后修改于 2025 年 4 月 19 日

PDOStatement::fetch 方法从结果集中检索下一行。它是 PHP 中处理数据库查询结果的基本方法。

基本定义

PDOStatement::fetch 从与 PDOStatement 对象关联的结果集中获取一行。它根据获取模式参数返回数据。

语法:public PDOStatement::fetch(int $mode = PDO::FETCH_DEFAULT, int $cursorOrientation = PDO::FETCH_ORI_NEXT, int $cursorOffset = 0): mixed。该方法返回下一行,如果没有更多行则返回 false。

基本获取示例

这显示了 fetch 的最简单用法,一次一行地检索行。

basic_fetch.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');
    
    while ($row = $stmt->fetch()) {
        echo "ID: {$row['id']}, Name: {$row['name']}, Email: {$row['email']}\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

此示例以关联数组(默认模式)获取行。while 循环一直持续到 fetch 返回 false。每行包含可以通过列名访问的列值。

使用不同模式获取

PDO 提供了多种获取模式来控制数据的返回方式。

fetch_modes.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 FROM users LIMIT 1');
    
    // Fetch as associative array
    $rowAssoc = $stmt->fetch(PDO::FETCH_ASSOC);
    print_r($rowAssoc);
    
    // Fetch as numeric array
    $rowNum = $stmt->fetch(PDO::FETCH_NUM);
    print_r($rowNum);
    
    // Fetch as object
    $rowObj = $stmt->fetch(PDO::FETCH_OBJ);
    echo $rowObj->name;
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这演示了三种常见的获取模式。FETCH_ASSOC 以列名作为键。FETCH_NUM 使用数字索引。FETCH_OBJ 创建一个匿名对象,其属性与列名匹配。

绑定列获取

PDO 允许将列绑定到 PHP 变量以直接访问。

fetch_bound.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');
    
    $stmt->bindColumn('id', $id);
    $stmt->bindColumn('name', $name);
    $stmt->bindColumn('email', $email);
    
    while ($stmt->fetch(PDO::FETCH_BOUND)) {
        echo "ID: $id, Name: $name, Email: $email\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这会在获取之前将列绑定到变量。FETCH_BOUND 在每次调用 fetch 时更新变量。变量必须通过引用传递给 bindColumn。

获取到现有对象

PDO 可以将数据直接获取到现有对象的属性中。

fetch_into.php
<?php

declare(strict_types=1);

class User {
    public $id;
    public $name;
    public $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');
    $user = new User();
    
    while ($stmt->fetch(PDO::FETCH_INTO, $user)) {
        echo "User: {$user->name} ({$user->email})\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这创建了一个 User 类,并将数据直接获取到其属性中。FETCH_INTO 为每一行重用同一个对象,更新其属性。该对象必须具有与列名匹配的属性。

使用自定义类获取

PDO 可以实例化一个类并用获取的数据填充其属性。

fetch_class.php
<?php

declare(strict_types=1);

class User {
    private $id;
    private $name;
    private $email;
    
    public function getId(): int {
        return $this->id;
    }
    
    public function getName(): string {
        return $this->name;
    }
    
    public function getEmail(): string {
        return $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');
    $stmt->setFetchMode(PDO::FETCH_CLASS, 'User');
    
    while ($user = $stmt->fetch()) {
        echo "User: {$user->getName()} ({$user->getEmail()})\n";
    }
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这创建了一个具有私有属性和 getter 方法的 User 类。setFetchMode 配置 PDO 来实例化 User 对象。每次获取都会创建一个新的 User 实例,其中包含当前行的数据。

获取单列

当您每行只需要一列时,FETCH_COLUMN 非常高效。

fetch_column.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 name FROM users');
    
    while ($name = $stmt->fetch(PDO::FETCH_COLUMN)) {
        echo "Name: $name\n";
    }
    
    // Alternative using fetchAll
    $names = $stmt->fetchAll(PDO::FETCH_COLUMN);
    print_r($names);
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这每行只获取 name 列。FETCH_COLUMN 每行返回一个单独的值。该示例展示了迭代获取和 fetchAll 来一次性获取所有值。

使用游标控制获取

高级应用程序可以在获取时控制游标位置。

fetch_cursor.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');
    
    // Get first row
    $first = $stmt->fetch();
    
    // Get last row (requires scrollable cursor)
    $last = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_LAST);
    
    // Get previous row
    $prev = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR);
    
    echo "First: {$first['name']}, Last: {$last['name']}, Previous: {$prev['name']}";
} catch (PDOException $e) {
    echo "Error: " . $e->getMessage();
}

这演示了使用 fetch 进行游标控制。FETCH_ORI_LAST 移动到最后一行。FETCH_ORI_PRIOR 获取前一行。请注意,必须在准备语句时请求可滚动游标。

最佳实践

来源

PHP PDOStatement::fetch 文档

本教程介绍了 PDOStatement::fetch 方法,并通过实际示例展示了不同的获取模式和高级用法场景。

作者

我的名字是 Jan Bodnar,我是一名充满激情的程序员,拥有丰富的编程经验。我从 2007 年开始撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出 所有 PHP PDO 函数