我正在尝试为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
}
Run Code Online (Sandbox Code Playgroud)
有没有办法重置声明或寻找第一行?
小智 9
请参阅此演示文稿中的幻灯片31,$statement->rewind()
如果它适用于缓冲查询,则可以执行此操作.如果您使用mysql,则可以使用PDO_MYSQL_ATTR_USE_BUFFERED_QUERY
以下方法模拟缓冲查询:
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
Run Code Online (Sandbox Code Playgroud)
@NoahGoodrich指向你.以下是一个始终有效的示例:
$it = new ArrayIterator($stmt->fetchAll());
Run Code Online (Sandbox Code Playgroud)
我写的这个小班包装了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);
}
}
}
Run Code Online (Sandbox Code Playgroud)