我正在流动this文章来创建数据库迭代器。我有类似的表格和记录。但是当我执行时,我得到了空白页面。我认为$data = new DbRowIterator($stmt);
上有问题,它没有返回正确的迭代器来在accept
类中运行FilterIterator
方法。我正在使用laravel
答案 0 :(得分:14)
这篇文章是一个恶作剧。它声称提供的技术可以加速PDO的数据库调用,但实际上它会大大减慢它们的速度。
它接地的场所也是错误的。 PDOStatement 已经可以遍历,你不需要使用foreach迭代PDOStatement的技巧。
基准测试部分(经常发生)是一种公然的骗局。这家伙正在比较显然消耗大量时间/内存的fetchAll()
,一次只能获取一行。即使这样,他的时间也比使用正确的解决方案更糟糕。
写这篇文章的人不知道PDO,而且 - 更糟糕的是 - 没有SQL。
他发明的所有内容已经存在于PDO和SQL中:
所以,为了得到这个人用这样的努力写的所有内容,你只需要几行PDO
$period = date_create("last_week")->format('Y-m-d 00:00:00');
$sql = 'SELECT * FROM `gen_contact` WHERE contact_modified > ? ORDER BY `contact_modified` DESC';
$stmt = $pdo->prepare($sql);
$stmt->execute([$period]);
foreach ($stmt as $row) {
echo sprintf(
'%s (%s)| modified %s',
$row->contact_name,
$row->contact_email,
$row->contact_modified
) . PHP_EOL;
}
这个代码将快多倍,因为它在数据库级别进行过滤,而不是获取整个表,然后在PHP端进行过滤。
截至您收到的错误,只需set PDO in exception mode并注意常规的PHP错误。
答案 1 :(得分:4)
PDOStatement不可迭代,它可以遍历:
它没有实现 \ Iterable 接口,而是 \ Traversable 接口,这意味着它可以在 foreach 中使用,但是您无法迭代手动覆盖它,因为它不会暴露它的内在行为。
我不认为这在目前的情况下有很大的不同,但两个界面之间仍然存在重大差异。
我偶然发现了这个问题,寻找一种方法来正确地迭代PDOStatement(不使用foreach)和文章提到的,虽然看起来很笨拙对我来说很好。
答案 2 :(得分:2)
正如@VincentChalnot所说 - PDO不返回Iterable类的实例,但它确实返回Traversable,并且事实证明PHP为Traversable对象提供了Iterator - IteratorIterator(http://php.net/manual/en/class.iteratoriterator.php)。
因此,如果你想使用任何PHP的built in Iterator classes,例如CachingIterator,使用PDOStatement,你就可以这样做:
$iterator = new CachingIterator(new IteratorIterator($stmt));