如何在PHP + Doctrine中执行一个大循环



我试图开发一个简单的"排名"脚本在PHP使用Symfony2 (MongoDB+Doctrine)。

    $users = $dm->createQueryBuilder('Account')
                ->sort('points', 'DESC')
                ->getQuery()
                ->execute();
    foreach($users as $user){
            // Do nothing
    }

我得到以下问题:

PHP致命错误:允许的内存大小为134217728字节耗尽(试图分配25字节)

我的数据库有80000个用户,所以$users拥有所有的用户。

嗯,我知道我可以修改php配置来允许更多的内存。我要这么做。但我正在寻找其他类型的解决方案(除了添加额外的内存到PHP配置)。

我认为我已经尝试开发它与"分页",但它也不工作(我得到错误在用户272,第三次迭代):

    $limit = 100;
    $skip = 0;
    $total = $dm->createQueryBuilder('Account')->count()->getQuery()->execute();
    $max = $total/$limit;
    while($skip<=$max){
        $users = $dm->createQueryBuilder('Account')
            ->sort('points', 'DESC')
            ->limit($limit)
            ->skip($skip*$limit) // 0x100, 1x100, 2x100, 3x100
            ->getQuery()
            ->execute();
        foreach($users as $user){
               // Do nothing
        }
        $skip++;
    }

你知道我该怎么做吗?

PS:我想我已经做了什么是建议在这篇文章:如何处理巨大的选择查询symfony和学说?

参见iterate()方法的文档。它就是为这个目的而设计的。

你可以使用iterate()方法来迭代一个大的结果,没有UPDATE或DELETE意图。从$query->iterate()返回的IterableResult实例实现了Iterator接口,因此您可以处理大型结果而不会出现内存问题…

当你使用它时不要忘记detach结果

Doctrine将所有实体保存在内存中。因此,对于批量更新,您需要清除缓存。

$dm->flush();
$dm->clear(); // Detaches all objects from Doctrine!

最新更新