PDO fetch方法改变了pdo对象本身

时间:2013-05-18 11:21:04

标签: php mysql pdo

从mysql切换到PDO我注意到fetch方法改变了PDO对象本身! 例如:

$res=$ps->fetchAll();
echo($res[0]['Mail']); //it'ok

//now i re-call the fetch method
$res=$ps->fetchAll();
echo($res[0]['Mail']); //no result!

为什么会这样?在mysql中我从未见过这个东西

3 个答案:

答案 0 :(得分:4)

对象仍包含您的数据,但它维护一个指向当前记录的内部指针。每次从结果集中获取记录时,指针都会前进到下一行。

对于fetchAll(),指针已前进到结果集的末尾,因此后续的fetchAll()调用不会返回任何结果。

如果需要再次调用fetchAll(),可以将指针倒回到结果集的开头。这可以通过缓冲查询完成:

$ps->setAttribute(PDO_MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
$ps->rewind();
$ps->fetchAll();

答案 1 :(得分:1)

fetch返回所有剩余/可用行,如果没有更多行可用,则返回FALSE;并且fetchAll将在单次尝试中返回所有可用行,之后的调用将返回FALSE,因为结果集中不会再有数据。

我们可以在上面的示例中重用数组$res

答案 2 :(得分:0)

您需要了解fetch*的作用:
当您从PDO向数据库发出查询时,数据库会过滤其数据,以将您要求的数据的结果集组合在一起。这可能涉及从硬盘读取数据,将其放入内存并将其保留一段时间。对于大型结果集,这些是花费的重要资源。当您从PDO fetch()时,一个结果从数据库的内部缓冲区复制到PHP的/ PDO的内部缓冲区,并作为数据数组返回给您。当您再次致电fetch()时,您会得到下一个结果,依此类推。

获取结果后,数据库可以释放该内存。客户端(您)获取了它要求的数据,因此数据库可以将其从内存中删除。您不能再次fetch()相同的数据;出于效率原因。

fetchAll()一次性获取所有结果并返回一个大数组。这与:

相同
$result = array();
while ($row = $pdo->fetch()) {
    $result[] = $row;
}

你也不能再做上述事了。

mysql中,与此相同:

$result = array();
while ($row = mysql_fetch_assoc($resultSet)) {
    $result[] = $row;
}

你也不能再这样做了。


可以回滚数据库中的结果集指针,以明确告诉它再次读取它已读取的内容,但这可能是非常低效的,应该避免。为了使您的应用程序快速运行,您应该只根据需要来回传输尽可能少的数据,并尽可能少地将数据存储在内存中。