是否可以倒带PDO结果?
我正在尝试为PDO语句的结果编写一个迭代器,但我找不到任何倒回到第一行的方法。我想避免调用fetchAll并存储所有结果数据的开销。是否可以倒带PDO结果?
// first loop works fine
foreach($statement as $result) {
// do something with result
}
// but subsequent loops don't
foreach($statement as $result) {
// never called
}
是否有正在重置陈述或寻求第一行的一些方法?
我敢肯定,这取决于数据库。因此,这是你应该尽量避免的。不过,我认为你可以通过启用buffered queries来实现你想要的。如果这不起作用,你总是可以将结果放入一个fetchAll
的数组中。这两种解决方案都会影响您的应用程序性能,因此如果结果集很大,请仔细考虑一下。
您可能需要查看一些可以扩展以提供对对象类似数组的访问的PHP SPL类。
- Standard PHP Library (SPL)我特别 建议你看看 ArrayIterator,ArrayObject的,并且 也许Iterator接口。
- Simple Tutorial
- Another Quick Tutorial
请参阅slide 31 from this presentation,如果它适用于缓冲查询,则可以执行$statement->rewind()
。如果您使用mysql,您可以通过使用PDO_MYSQL_ATTR_USE_BUFFERED_QUERY
模拟缓冲查询:
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, 1);
@NoahGoodrich指出你SPL。下面是一个总是有效的例子:
$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);
}
}
}
问很久以前,但目前还有另一种解决方案。
方法PDOStatement::fetch()
可以接收第二参数,即光标方向,其中一个参数为PDO::FETCH_ORI_*
常数中的一个。这些参数仅在PDOStatement
使用属性PDO::ATTR_CURSOR
作为PDO::CURSOR_SCROLL
创建时才有效。
这样你可以导航如下。在docs和PDO predefined constants
$sql = "Select * From Tabela";
$statement = $db->prepare($sql, array(
PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL,
));
$statement->execute();
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_NEXT); // return next
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_PRIOR); // return previous
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_FIRST); // return first
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_LAST); // return last
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_ABS, $n); // return to $n position
$statement->fetch(PDO::FETCH_BOTH, PDO::FETCH_ORI_REL, $n); // return to $n position relative to current
更多信息。
注意:使用PDO::FETCH_BOTH
因为是默认值,只需为您的项目自定义它。
PdoStatement已经实现了Traversable – troelskn 2008-11-10 18:07:15