PHP中使用Generator处理大数据集的5个实战技巧
1. Generator基础:理解yield关键字
Generator函数在调用时不会立即执行,而是返回一个迭代器对象。每次迭代时执行到yield语句时返回一个值,并暂停执行直到下一次迭代。
<?php
function generateNumbers($max) {
for ($i = 1; $i <= $max; $i++) {
yield $i;
}
}
foreach (generateNumbers(1000000) as $number) {
echo $number . "n";
}
?>
这个例子即使生成100万个数字,内存消耗始终保持在极低水平。
2. 实战案例:大文件逐行处理
处理GB级日志文件时,传统方法会导致内存溢出,Generator是完美解决方案:
<?php
function readLargeFile($filename) {
$file = fopen($filename, 'r');
while (!feof($file)) {
yield fgets($file);
}
fclose($file);
}
foreach (readLargeFile('access.log') as $line) {
// 处理每行日志
processLogLine($line);
}
?>
3. 生成器委托(PHP 7.0+)
PHP 7引入的yield from
语法可以委托给另一个生成器:
<?php
function generatorA() {
yield 1;
yield 2;
}
function generatorB() {
yield from generatorA();
yield 3;
}
foreach (generatorB() as $value) {
echo $value; // 输出1, 2, 3
}
?>
4. 内存敏感的数据处理
数据库百万级数据处理的最佳实践:
<?php
function fetchBigData($query) {
$stmt = $pdo->query($query);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
yield $row;
}
}
foreach (fetchBigData("SELECT * FROM large_table") as $row) {
// 处理每行数据
processData($row);
}
?>
5. 生成器作为协程(双向通信)
PHP生成器支持双向通信,可以构建简单的协程:
<?php
function logger() {
while (true) {
$message = yield;
echo date('[Y-m-d H:i:s]') . " $messagen";
}
}
$log = logger();
$log->send('User logged in');
$log->send('Data processed');
?>
掌握Generator技术可以显著提升PHP处理大数据的能力,是现代PHP开发者必备的高级技能。