PHP处理大数据量循环记录的高效解决方案与内存优化技巧

[id_[id_972043423]09618341]

PHP处理大数据量循环记录的高效解决方案与内存优化技巧

当我们需用 php 处理大数据量时,像循环数据库的所有记录这种情况,此记录可能会很大,像有 100 万行。那么,通过传统办法就不行了。首先是通过 web 访问,php 有超时时间,默认是 30 秒。只能通过 php cli 的方式来执行,这样就不存在超时时间了。然而,因为数据量很大,在 php 循环时需要将全部数据载入内存中执行,正因为数据量太大,所以 php 会报出“Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 4096 bytes)”这样的错误。PHP 通过生成器函数能够极大地节省内存开销。

生成器函数

生成器函数的外观与普通函数相似。普通函数会返回一个值,而生成器能够通过 yield 产出多个想要的值。只要一个函数中包含 yield,那么它就是一个生成器函数。

当调用一个生成器时,它会返回一个可遍历的对象。当对这个对象进行遍历(比如通过 foreach 循环),PHP 会在每次需要值的时候调用对象的遍历方法,并且在产生一个值之后保存生成器的状态,以便在需要产生下一个值时能恢复调用状态。

yield关键字

生成器函数的核心是 yield 关键字。yield 关键字与 return 申明有相似之处。普通 return 会返回值并终止函数执行,而 yield 会返回一个值给循环调用此生成器的代码,并且只是暂停执行生成器函数。

一个简单的例子

以上例子会输出:

1
2
3

遍历数据库实例

当前我们需要对数据库的 emp 表进行循环。该表拥有 100 万行记录。我们要循环这个表并修改 mgr 的字段值。

未使用生成器

$db = sf::getLib('db');
从“emp”表中选择所有数据,条件是“mgr = 1”,然后按照“id”升序进行排序。
$query = $db->query($sql);
当 ($row = $db->fetch_array($query)) 时:
$db 执行一条更新语句,将 emp 表中 id 为 '{$row['id']}' 的记录的 mgr 字段更新为 2 。
输出“id:”以及变量 $row['id'] 的值,并换行
}

当数据量较小时,这不会产生问题。然而,倘若数据量较大,就无法执行,并且会出现内存超过限制的错误。

使用生成器

function test_yield(){
    $db = sf::getLib('db');
从“emp”表中选择所有内容,条件是“mgr = 1”,并且按照“id”升序进行排序。
    $query = $db->query($sql);
当 $row 等于 $db 调用 fetch_array 方法返回的结果时,进行以下操作;在每次循环中,$row 会被更新为 $db 执行 $query 语句后返回的下一行数据;只要 $row 不为空,就会持续执行循环体中的代码;当 $row 为空时,循环结束。
        yield $row;
    }
}
对于每个由 test_yield() 生成的项($item):
    $db->exec("update emp set mgr = 2 where id = '{$row['id']}'");
输出“id:”与$item['id']拼接后的内容,并换行
}

程序借助 test_yield 这个生成器函数能够正常执行,同时内存也不会超限。

你可能想看:
« 上一篇
下一篇 »

相关推荐

php实时推送,php实地培训

2026年10月05日

48阅读

php乱码出现问号的原因,php乱码出现问号的原因有哪些

2026年10月05日

40阅读

php一句话木马,一句话木马ctf

2026年10月05日

43阅读

php获取数组长度,php中如何获取数组的长度

2026年10月05日

44阅读

php面试题库及答案,php程序员面试真题库

2026年10月05日

42阅读

phpcontent-type修改,php源码二次修改需要多少钱

2026年10月05日

38阅读