我正在尝试为PDO语句的结果编写一个迭代器,但我找不到任何重绕到第一行的方法.我想避免调用fetchAll和存储所有结果数据的开销.
// first loop works fine foreach($statement as $result) { // do something with result } // but subsequent loops don't foreach($statement as $result) { // never called }
有没有办法重置声明或寻找第一行?
我很确定这是依赖于数据库的.因此,您应该尽量避免这种情况.但是,我认为您可以通过启用缓冲查询来实现您想要的功能.如果这不起作用,您始终可以将结果拉入数组中fetchAll
.这两种解决方案都会对您的应用程序性能产生影响,因此如果结果集很大,请三思而后行.
请参阅此演示文稿中的幻灯片31,$statement->rewind()
如果它适用于缓冲查询,则可以执行此操作.如果您使用mysql,则可以使用PDO_MYSQL_ATTR_USE_BUFFERED_QUERY
以下方法模拟缓冲查询:
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
@NoahGoodrich指向你.以下是一个始终有效的示例:
$it = new ArrayIterator($stmt->fetchAll());
我写的这个小班包装了PDOStatement.它仅存储获取的数据.如果这不起作用,您可以移动缓存以读取和写入文件.
// Wrap a PDOStatement to iterate through all result rows. Uses a // local cache to allow rewinding. class PDOStatementIterator implements Iterator { public $stmt, $cache, $next; public function __construct($stmt) { $this->cache = array(); $this->stmt = $stmt; } public function rewind() { reset($this->cache); $this->next(); } public function valid() { return (FALSE !== $this->next); } public function current() { return $this->next[1]; } public function key() { return $this->next[0]; } public function next() { // Try to get the next element in our data cache. $this->next = each($this->cache); // Past the end of the data cache if (FALSE === $this->next) { // Fetch the next row of data $row = $this->stmt->fetch(PDO::FETCH_ASSOC); // Fetch successful if ($row) { // Add row to data cache $this->cache[] = $row; } $this->next = each($this->cache); } } }