2026-04-08 13:06:46
yield关键字在PHP中用于创建生成器,实现内存高效的迭代操作,支持延迟计算、双向通信及模块化代码设计,尤其适合处理大规模数据或复杂交互场景。
一、yield的核心功能与优势内存高效迭代
生成器通过暂停函数执行并逐个返回值,避免一次性加载所有数据到内存。例如处理百万级数据库记录时,生成器每次仅保留当前记录,内存占用显著低于传统数组。
示例:读取大型日志文件时,逐行返回内容而非全量加载:
function readLogFile($filename) { $file = fopen($filename, 'r'); while (($line = fgets($file)) !== false) { yield $line; } fclose($file);}foreach (readLogFile('large_log.txt') as $line) { if (strpos($line, 'ERROR') !== false) { echo "Error: $line"; }}延迟计算(Lazy Evaluation)
生成器仅在迭代时生成值,支持无限序列或高计算成本场景。例如生成斐波那契数列:
function fibonacci($limit) { $a = 0; $b = 1; while ($a <= $limit) { yield $a; [$a, $b] = [$b, $a + $b]; }}foreach (fibonacci(100) as $num) { echo "$num "; // 输出:0 1 1 2 3 5...}与return的区别
yield暂停函数执行并返回当前值,下次迭代从暂停处继续;return直接终止函数。生成器可多次返回值,而函数只能返回一次。
发送值到生成器:通过send()方法向生成器内部传递数据,yield表达式接收该值。
function coroutine() { $value = (yield "Initial value"); // 接收外部发送的值 echo "Received: $valuen"; yield "Final step";}$generator = coroutine();echo $generator->current(); // 输出:Initial value$generator->send("Hello"); // 发送值到生成器// 输出:Received: Hello协程应用:生成器可模拟轻量级并发,单线程内交替执行多个任务(需配合事件循环库如ReactPHP)。
大数据处理
分页加载:按需加载数据库结果集,避免全量查询。function getPaginatedData($page, $perPage) { $offset = ($page - 1) * $perPage; // 模拟数据库查询(实际应使用PDO预处理) for ($i = $offset + 1; $i <= $offset + $perPage; $i++) { yield ["id" => $i, "name" => "Item $i"]; }}foreach (getPaginatedData(2, 5) as $item) { print_r($item); // 输出第6-10条数据}
文件解析
CSV/XML处理:逐行或逐节点解析,减少内存峰值。function parseCSV($filename) { $file = fopen($filename, 'r'); $headers = fgetcsv($file); // 读取表头 while ($row = fgetcsv($file)) { yield array_combine($headers, $row); } fclose($file);}
流式数据流
实时数据处理:如传感器数据采集、网络流处理,生成器可逐块处理数据流。
算法实现
图遍历:生成器可逐步生成搜索路径,避免递归深度过大。function bfs($graph, $start) { $queue = [$start]; while (!empty($queue)) { $vertex = array_shift($queue); yield $vertex; foreach ($graph[$vertex] ?? [] as $neighbor) { $queue[] = $neighbor; } }}
总结:PHP的yield关键字通过生成器机制,提供了内存高效的迭代方案,尤其适合大数据处理、延迟计算及复杂交互场景。结合yield from和双向通信能力,可进一步优化代码结构与功能实现。