fetchAll()

1. 定义

PDOStatement::fetch()方法不同,该方法返回结果集中剩余的所有行。

注:

  • 如果一次性获取一个很大的结果集可能加重系统负担,并占用大量网络资源。可以考虑在数据库端处理结果集,例如使用WHERE条件语句或ORDER BY ... LIMIT ...语句来限定返回的结果数

2. 语法

PDOStatement::fetchAll ([ int $fetch_style [, mixed $fetch_argument [, array $ctor_args = array() ]]] ) : array

3. 参数说明

参数 可选性 数据类型 描述
$fetch_style 可选 整型或常量 PDO::FETCH_*系列的常量之一,默认为PDO::FETCH_BOTH
$fetch_argument 可选 mixed 根据fetch_style参数,传入的参数
$ctor_args 可选 数组 fetch_style参数为PDO::FETCH_CLASS时,指定类的构造函数参数列表

其中,$fetch_style的值有以下可选项:

  • PDO::FETCH_ASSOC:结果集返回一个索引为列名的关联数组
  • PDO::FETCH_BOTH:默认值。结果集分别返回以索引为列名和从零开始的数字的关联数组
  • PDO::FETCH_BOUND:返回TRUE,并将结果集中的列值分配给使用PDOStatement::bindColumn()方法绑定到的 PHP 变量
  • PDO::FETCH_CLASS:返回所请求类的新实例,并将结果集的列值映射到该类中的命名属性。如果$fetch_style包含PDO::FETCH_CLASSTYPE,则类名由第一列的值决定
  • PDO::FETCH_INTO:更新请求的类中已存在的实例,并将结果集的列值映射到该类中的命名属性
  • PDO::FETCH_LAZY:相当于PDO::FETCH_BOTH | PDO::FETCH_OBJ,创建用来访问的对象变量名
  • PDO::FETCH_NUM:结果集返回一个数字索引的数组
  • PDO::FETCH_OBJ:结果集返回一个以列名为属性名的匿名对象
  • PDO::FETCH_COLUMN:返回结果集中指定列的所有值数组,需在$fetch_argument参数指定列序号(从零开始)
  • PDO::FETCH_FUNC:将每行的列作为参数传递给指定函数,并返回调用函数后的结果,须在$fetch_argument参数指定函数名

另外,如果想获取结果集中每列的唯一值,需要在$fetch_style参数指定PDO::FETCH_COLUMN | PDO::FETCH_UNIQUE;如果想获取根据指定列分组值的关联数组,需要在$fetch_style参数指定PDO::FETCH_COLUMN | PDO::FETCH_GROUP

4. 示例

<?php

// PDOStatement::fetchAll()
// 返回结果集中**剩余**的所有行

class Movie
{
    public $name = '';
    public $rate = 9.0;

    public function __construct($name = '电影名称', $rate)
    {
        $this->name = $name;
        $this->rate = $rate;
    }
    public function getName()
    {
        return $this->name;
    }
}

function callback($name, $rate)
{
    return "$name 评分为 $rate";
}

try {
    $config = ['driver' => 'mysql', 'host' => 'localhost', 'dbname' => 'test', 'charset' => 'utf8', 'user' => 'root', 'pwd' => 'mysql'];
    $dsn = sprintf('%s:host=%s;dbname=%s;charset=%s', $config['driver'], $config['host'], $config['dbname'], $config['charset']);
    $conn = new PDO($dsn, $config['user'], $config['pwd']);
} catch (PDOException $e) {
    error_log($e->getMessage());
    echo $e->getMessage();
}

try {
    $sql = 'SELECT `name`,`rate`,`cover`,`url` FROM `movie` WHERE `id` > 15 ORDER BY `id`';
    $stmt = $conn->prepare($sql);

    $stmt->execute();
    $res = $stmt->fetchAll(PDO::FETCH_ASSOC);// 返回一个列名为索引的关联数组

    $stmt->execute();// 因为在上一个执行语句中,无剩余行,结果集为空,所以重新执行以获取结果集
    $res = $stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'Movie', ['name', 'rate']);// 返回一个请求类的新实例数组,配合 PDO::FETCH_PROPS_LATE 同时使用时,将调用指定类的构造函数
    var_dump($res);
    /* 输出:
    ...
    [3]=>
    object(Movie)#6 (3) {
      ["name"]=>
      string(15) "你的名字。"
      ["rate"]=>
      string(3) "8.4"
      ["cover"]=>
      string(74) "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2395733377.jpg"
      ["url"]=>
      string(42) "https://movie.douban.com/subject/26683290/"
    }
    ...
    */

    $stmt->execute();// 因为在上一个执行语句中,无剩余行,结果集为空,所以重新执行以获取结果集
    $res = $stmt->fetchAll(PDO::FETCH_COLUMN, 0);//  返回结果集中指定列号的列值数组
    var_dump($res);
    /* 输出:
    array(5) {
      [0]=>
      string(12) "头号玩家"
      [1]=>
      string(12) "无名之辈"
      [2]=>
      string(12) "盗梦空间"
      [3]=>
      string(15) "你的名字。"
      [4]=>
      string(21) "三傻大闹宝莱坞"
    }
    */

    $stmt->execute();// 因为在上一个执行语句中,无剩余行,结果集为空,所以重新执行以获取结果集
    $res = $stmt->fetchAll(PDO::FETCH_FUNC, 'callback');//  将每行的列作为参数传递给指定函数,并返回调用函数后的结果
    var_dump($res);
    /* 输出:
    array(5) {
      [0]=>
      string(26) "头号玩家 评分为 8.7"
      [1]=>
      string(26) "无名之辈 评分为 8.1"
      [2]=>
      string(26) "盗梦空间 评分为 9.3"
      [3]=>
      string(29) "你的名字。 评分为 8.4"
      [4]=>
      string(35) "三傻大闹宝莱坞 评分为 9.2"
    }
    */

    // 插入两个重复行以测试分组
    $conn->query("INSERT INTO `movie`(`name`, `rate`, `url`, `cover`, `cover_x`, `cover_y`) VALUES ('泰坦尼克号', 9.4, 'https://movie.douban.com/subject/1292722/', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p457760035.jpg', 2015, 3000)");
    $conn->query("INSERT INTO `movie`(`name`, `rate`, `url`, `cover`, `cover_x`, `cover_y`) VALUES ('泰坦尼克号', 9.4, 'https://movie.douban.com/subject/1292722/', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p457760035.jpg', 2015, 3000)");
    $conn->query("INSERT INTO `movie`(`name`, `rate`, `url`, `cover`, `cover_x`, `cover_y`) VALUES ('泰坦尼克号', 9.4, 'https://movie.douban.com/subject/1292722/', 'https://img3.doubanio.com/view/photo/s_ratio_poster/public/p457760035.jpg', 2015, 3000)");

    $stmt->execute();// 因为在上一个执行语句中,无剩余行,结果集为空,所以重新执行以获取结果集
    $res = $stmt->fetchAll(PDO::FETCH_COLUMN | PDO::FETCH_GROUP);//  获取结果集中每一列的唯一值
    var_dump($res);
    /* 输出:
    array(6) {
      ["头号玩家"]=>
      array(1) {
        [0]=>
        string(3) "8.7"
      }
      ["无名之辈"]=>
      array(1) {
        [0]=>
        string(3) "8.1"
      }
      ["盗梦空间"]=>
      array(1) {
        [0]=>
        string(3) "9.3"
      }
      ["你的名字。"]=>
      array(1) {
        [0]=>
        string(3) "8.4"
      }
      ["三傻大闹宝莱坞"]=>
      array(1) {
        [0]=>
        string(3) "9.2"
      }
      ["泰坦尼克号"]=>
      array(3) {
        [0]=>
        string(3) "9.4"
        [1]=>
        string(3) "9.4"
        [2]=>
        string(3) "9.4"
      }
    }
    */
} catch (Exception $e) {
    echo "发生了错误:", $e->getMessage();
}

5. 延展阅读