创建PDO迭代器

时间:2016-09-09 11:37:19

标签: php pdo

我正在流动this文章来创建数据库迭代器。我有类似的表格和记录。但是当我执行时,我得到了空白页面。我认为$data = new DbRowIterator($stmt);上有问题,它没有返回正确的迭代器来在accept类中运行FilterIterator方法。我正在使用laravel

3 个答案:

答案 0 :(得分:14)

这篇文章是一个恶作剧。它声称提供的技术可以加速PDO的数据库调用,但实际上它会大大减慢它们的速度。

它接地的场所也是错误的。 PDOStatement 已经可以遍历,你不需要使用foreach迭代PDOStatement的技巧。

基准测试部分(经常发生)是一种公然的骗局。这家伙正在比较显然消耗大量时间/内存的fetchAll(),一次只能获取一行。即使这样,他的时间也比使用正确的解决方案更糟糕。

写这篇文章的人不知道PDO,而且 - 更糟糕的是 - 没有SQL。

他发明的所有内容已经存在于PDO和SQL中

  1. PDOStatement 已经可以遍历。无需重新发明轮子。
  2. 最重要的部分:过滤必须在SQL中完成,而不是在PHP中完成。这是一本教科书规则。如果您只需要250000条记录中的63992条,则首先应选择63992条。如果您要求数据库为您选择记录,那么它将无法比得更快。
  3. 所以,为了得到这个人用这样的努力写的所有内容,你只需要几行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));