使用yield生成器可高效处理百万级数据流:一、逐行读取大日志;二、流式解析csv;三、数据库游标分页;四、惰性生成id序列;五、excel分块解析,均实现单行/单批内存驻留。

如果您需要处理百万级数据流,但遭遇内存耗尽或脚本崩溃,则很可能是因传统数组方式一次性加载全部数据所致。以下是多种基于yield关键字的生成器实战方案:
一、逐行读取超大文本日志文件
该方法利用文件句柄配合yield实现单行内存驻留,避免将整个GB级日志载入内存。每次迭代仅读取并返回一行,处理完毕后立即释放该行所占空间。
1、使用fopen以只读模式打开日志文件;
2、在while循环中调用fgets逐行读取,对每行执行trim()去除首尾空白;
3、每读取一行即通过yield返回该行字符串;
4、使用fclose关闭文件句柄;
5、通过foreach遍历生成器返回的每一行进行业务逻辑处理。
二、流式解析百万行CSV文件
此方案结合fgetcsv与yield,确保任意大小的CSV文件均可安全处理。生成器每次产出一个索引数组,代表CSV中的一行字段,内存中始终仅存当前行数据。
1、调用fopen打开CSV文件,指定'r'模式;
2、在while循环中执行fgetcsv($handle),判断返回值是否为false;
3、若成功读取一行,则yield该行数据(自动跳过空行和BOM头);
4、循环结束后显式调用fclose($handle);
5、在外部foreach中直接对每行$data数组进行字段提取、转换或入库操作。
三、数据库海量记录分页游标迭代
该方式绕过LIMIT/OFFSET低效分页,改用游标式单向流查询。生成器每次fetch一条记录并yield,彻底规避全表扫描与临时表开销。
1、准备PDO预处理语句,SQL中不带LIMIT,仅按主键升序查询;
2、执行$stmt->execute()获取结果集;
3、在while循环中调用$stmt->fetch(PDO::FETCH_ASSOC),判断是否为空;
4、非空时yield当前$row关联数组;
5、foreach遍历时可对每条记录做实时转换、API推送或批量写入另一库表。
四、惰性生成数字序列用于ID批量处理
当需对百万级ID执行节点更新、缓存刷新等操作时,此方法避免构造完整ID数组。生成器按需输出整数,每个ID仅在被消费瞬间存在于内存。
1、定义生成器函数xrange($start, $end, $step = 1),内部使用for循环;
2、循环体内每轮执行yield $i,不声明任何中间数组;
3、调用该函数获得Generator对象;
4、在foreach中获取每个$id,并立即调用node_load($id)或对应业务函数;
5、确保业务操作完成后才进入下一轮迭代,防止并发资源争用。
五、Excel百万行数据分块yield解析
针对PHP-ExcelReader或PhpSpreadsheet等库的高内存占用问题,该方案将工作表按行切片,每批yield固定行数的二维数组,控制单次内存峰值。
1、打开Excel文件并获取活动工作表对象;
2、获取总行数$highestRow,设定每批处理1000行;
3、外层for循环按批次起始行号递进,内层for循环遍历当前批次所有行;
4、每行调用getCellByColumnAndRow获取单元格值,组装为$rowData;
5、当前批次结束时yield $rowData数组,不累积跨批次数据。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











