PHP PDOStatement::fetch讲解
在PHP的PDO(PHP Data Objects)扩展中,PDOStatement类是用于处理预处理语句结果的核心类,而fetch方法是获取结果集中下一行数据最常用的接口,掌握它的用法能帮助我们灵活处理数据库查询结果。
方法定义
PDOStatement::fetch的方法签名如下:
public mixed PDOStatement::fetch(int $mode = PDO::FETCH_DEFAULT, int $cursorOrientation = PDO::FETCH_ORI_NEXT, int $cursorOffset = 0)
该方法返回结果集的下一行数据,如果没有更多行则返回false。参数说明如下:
$mode:可选参数,指定返回数据的格式,默认值为PDO::FETCH_DEFAULT,即使用
PDOStatement::setFetchMode设置的模式,如果未设置则默认返回关联数组和索引数组的结合形式。$cursorOrientation:可选参数,指定游标移动的方向,默认值为PDO::FETCH_ORI_NEXT,即移动到下一行,仅对可滚动游标有效。
$cursorOffset:可选参数,指定游标偏移量,默认值为0,仅对可滚动游标有效。
常用返回模式
fetch方法的$mode参数支持多种返回模式,实际开发中最常用的有以下几种:
1. PDO::FETCH_ASSOC(关联数组模式)
该模式返回以列名作为键名的关联数组,适合通过列名快速获取对应字段的值。
<?php
// 假设已经建立了PDO连接,保存在$pdo变量中
$sql = "SELECT id, name, age FROM users WHERE age > :age";
$stmt = $pdo->prepare($sql);
$stmt->execute([':age' => 18]);
// 使用关联数组模式获取第一行数据
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
echo "用户ID:" . $row['id'] . "<br>";
echo "用户名:" . $row['name'] . "<br>";
echo "用户年龄:" . $row['age'] . "<br>";
}
?>2. PDO::FETCH_NUM(索引数组模式)
该模式返回以列在结果集中的位置(从0开始)作为键名的索引数组,适合按字段顺序获取值,内存占用相对更小。
<?php
$sql = "SELECT id, name, age FROM users WHERE age > :age";
$stmt = $pdo->prepare($sql);
$stmt->execute([':age' => 18]);
// 使用索引数组模式获取第一行数据
$row = $stmt->fetch(PDO::FETCH_NUM);
if ($row) {
echo "用户ID:" . $row[0] . "<br>";
echo "用户名:" . $row[1] . "<br>";
echo "用户年龄:" . $row[2] . "<br>";
}
?>3. PDO::FETCH_OBJ(对象模式)
该模式返回一个匿名对象,对象的属性名对应结果集的列名,适合以面向对象的方式操作数据。
<?php
$sql = "SELECT id, name, age FROM users WHERE age > :age";
$stmt = $pdo->prepare($sql);
$stmt->execute([':age' => 18]);
// 使用对象模式获取第一行数据
$row = $stmt->fetch(PDO::FETCH_OBJ);
if ($row) {
echo "用户ID:" . $row->id . "<br>";
echo "用户名:" . $row->name . "<br>";
echo "用户年龄:" . $row->age . "<br>";
}
?>4. PDO::FETCH_CLASS(指定类模式)
该模式可以将结果集数据映射到指定类的实例中,类的属性名需要和列名对应,适合结合自定义数据模型使用。
<?php
// 定义用户类
class User {
public $id;
public $name;
public $age;
public function getInfo() {
return "ID:{$this->id},姓名:{$this->name},年龄:{$this->age}";
}
}
$sql = "SELECT id, name, age FROM users WHERE age > :age";
$stmt = $pdo->prepare($sql);
$stmt->execute([':age' => 18]);
// 使用指定类模式获取第一行数据
$row = $stmt->fetch(PDO::FETCH_CLASS, 'User');
if ($row) {
echo $row->getInfo() . "<br>";
}
?>循环获取所有结果
通常需要遍历结果集获取所有符合条件的行,结合while循环和fetch方法即可实现:
<?php
$sql = "SELECT id, name, age FROM users WHERE age > :age";
$stmt = $pdo->prepare($sql);
$stmt->execute([':age' => 18]);
// 循环获取所有行数据,使用关联数组模式
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo "用户ID:{$row['id']},姓名:{$row['name']},年龄:{$row['age']}<br>";
}
?>注意事项
fetch方法每次调用都会移动结果集的游标,重复调用会依次返回下一行数据,直到没有更多数据返回false。如果结果集为空,第一次调用
fetch就会返回false,因此使用时建议先判断返回值再操作数据。可滚动游标需要在准备语句时通过
PDO::ATTR_CURSOR属性设置为PDO::CURSOR_SCROLL才能使用,默认游标是正向不可滚动的,仅支持PDO::FETCH_ORI_NEXT方向。使用
PDO::FETCH_CLASS模式时,如果类的属性未公开,默认会通过构造函数注入数据,若类没有构造函数则会直接设置属性值,需要注意类的访问控制。
总结
PDOStatement::fetch是PDO中处理单行查询结果的核心方法,通过不同的$mode参数可以灵活选择数据返回格式,适配不同的开发场景。实际使用中可以根据需求选择合适的返回模式,结合循环实现批量数据的处理,同时注意游标移动和返回值的判断,避免出现逻辑错误。