php - 在无缓冲查询的上下文中,foreach 是否等同于 while?

标签 php mysql pdo

我想知道——如果这段代码:

// example 1
$statement = $pdo->query('SELECT * FROM table'); // MySQL
while ($row = $statement->fetch())
{
  // doing something interesting
}

相当于这段代码:

// example 2
$statement = $pdo->query('SELECT * FROM table'); // MySQL
foreach ($statement as $row)
{
  // doing something interesting
}

在 MySQL 的无缓冲查询的上下文中? (我知道循环给出相同的结果。)

或者换句话说:

我试过类似的东西:

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);

$statement = $pdo->query('SELECT * FROM table WHERE x = 1');
while(...) OR foreach(...)
{
  // some magic
}
 OR
$statement->fetch(); // just fetch(), not fetchAll()

$statement = $pdo->query('SELECT * FROM table WHERE x = 2'); // MySQL
...

和:

  1. whileforeach 的情况下,代码运行没有错误。
  2. 如果只是 fetch(),我会得到 error: 2014

看来,我回答了我自己的问题;)但我仍然不确定。我也找不到可以回答我的问题的任何文档或 SO 问题。

最佳答案

PHP 5.5.12, window

我做了更多的测试。我创建了一个包含 100 000 条记录的表,并检查了使用不同方法对表中的所有值求和时占用了多少内存:

+----------+-------------+--------+
| method   | memory used | time   |
+----------+-------------+--------+
| fetchAll | 69.9157 MB  | 7.20 s |  // <-- fails if memory_limit < 69 M
| while    | 0.2494 MB   | 3.24 s |
| foreach  | 0.2494 MB   | 0.98 s |  // <-- here I disagree with Ollie
+----------+-------------+--------+

考虑到我的问题和上面的测试,我得出结论:

  • 使用foreachwhile 缓冲查询方面是等价的:这两种方法都是逐行读取,并且在执行循环后所有数据都以这种方式获取,下一个查询不会抛出error 2014
  • foreach不会做类似 fetchAll 的事情在遍历 PDOStatement 之前获取整个结果集: 如果是这样,测试将在 memory_limit < 69M 时失败(恕我直言:这很合逻辑,因为 PDOStatement 实现了 Traversable 接口(interface))。所以我不能同意 Ollie Jones 的回答(至少在我的计算机和环境中)。

关于php - 在无缓冲查询的上下文中,foreach 是否等同于 while?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32417524/

相关文章:

PHP int被MySQL转换为不同的字符串

php - mysql服务器端口号

mysql - Laravel 查询构建内连接

php - 将表单值附加到帖子上的隐藏 XML 字符串

mysql - PHP 从 HTML 字段获取数据

php - 拉维尔 4.2 : Slow queries when using an external MySQL server

php - 使用带有 PDO 的数组更新多个 MySQL 表列

PHP - (PDO) 使用绑定(bind)变量执行

php - 如何从 COM DLL 返回包含多个空字符的 BSTR

php - codeIgniter 故障转移阵列