【问题标题】:How does PHP PDO::query actually do?PHP PDO::query 实际上是如何做的?
【发布时间】:2017-04-23 23:46:55
【问题描述】:

对 PDO::query 的作用有点困惑。完全理解它与准备和执行之间的区别,但是不清楚查询是否运行提取。根据 PHP.net:

PDO::query — 执行 SQL 语句,将结果集作为 PDOStatement 对象返回

证明:

$s = $pdo->query('SELECT * FROM user');
var_dump($s);

哪个输出:

object(PDOStatement)#2 (1) {
  ["queryString"]=> string(18) "SELECT * FROM user"
}

所以它清楚地为我们提供了一个准备运行 fetch 或 fetchAll 的 PDOStatement 对象。然而。以下代码取自 PHP.net 手册:

$sql = 'SELECT name, color, calories FROM fruit ORDER BY name';
foreach ($conn->query($sql) as $row) {
    print $row['name'] . "\t";
    print $row['color'] . "\t";
    print $row['calories'] . "\n";
}

这表明运行 PDO::query 实际上在内部运行 fetch 并返回结果(在方法的初始描述中提到过)。但是,如果这是真的,那么随后对 fetch 的调用应该返回第二行,但它没有返回,您仍然会得到第一行。

查询是否运行提取并重置指针,以便后续提取也返回第一行?如果是这样,这不是表现不佳吗?为什么你可以循环查询并获得多行?它是否使用yield运行某种协程?此外,为什么在 PDOStatement 对象中看不到获取的数据?据推测,他们正在使用 __set_state 和 __debugInfo 魔术方法隐藏这些数据

【问题讨论】:

    标签: php pdo


    【解决方案1】:

    这与 PHP PDO::query 的实际作用无关。而是PDOStatement 实际上是什么。它是an object that supports a Traversable interface,所以可以迭代。并且在迭代时,它会在内部调用fetch()

    不清楚查询是否运行提取

    PDO::query 从不运行提取。 PDOStatement 可以。在下一行中,为了简洁起见,使用了简短的语法。

    foreach ($conn->query($sql) as $row)
    

    虽然可以写成

    $stmt = $conn->query($sql);
    foreach ($stmt as $row)
    

    因为foreach 正在迭代结果,由查询返回,而不是一次又一次地运行查询

    为什么在PDOStatement 对象中看不到提取的数据?

    因为没有这样的数据。

    希望现在一切都清楚了

    【讨论】:

    • 这里没有协程或yield。使用旧的(现已弃用的)MySQL 函数,这实际上更清晰一些。
    • 在 MySQL 接收(并执行)SELECT 后,它会保存结果集。每次调用 mysql_fetch_row 都会要求 MySQL 推送结果集中的下一项(如 SQL 游标)。
    • 所以你看到没有 PHP+MySQL 协程(跨应用程序协程?),也没有 yield(从什么产生?SELECT LIMIT A.B?)。
    • 我不敢苟同(尽管我对此不确定),因为我记得不久前曾根据内存消耗测试过这个确切的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-11
    • 2010-11-26
    • 2015-06-23
    • 2017-12-26
    • 2016-10-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多