PHP 生成器(Generators)是一种特殊的函数,允许你在不需要一次性生成所有数据的情况下逐步生成值。这在处理大数据集或需要延迟计算时非常有用。生成器使用 yield
关键字来生成值,而不是使用 return
来返回一个完整的数组。
以下是一些常见的 PHP 生成器使用场景和示例:
生成器函数使用 yield
来生成值。每次调用生成器的 next()
方法时,生成器会执行到下一个 yield
语句。
function simpleGenerator() {
yield 1;
yield 2;
yield 3;
}
$generator = simpleGenerator();
foreach ($generator as $value) {
echo $value . "\n";
}
输出:
1
2
3
foreach
结合生成器可以与 foreach
循环结合使用,逐步生成值。
function rangeGenerator($start, $end) {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
foreach (rangeGenerator(1, 5) as $number) {
echo $number . "\n";
}
输出:
1
2
3
4
5
生成器不仅可以生成值,还可以生成键值对。
function keyValueGenerator() {
yield 'a' => 1;
yield 'b' => 2;
yield 'c' => 3;
}
foreach (keyValueGenerator() as $key => $value) {
echo "$key: $value\n";
}
输出:
a: 1
b: 2
c: 3
yield from
yield from
允许生成器委托给另一个生成器或可迭代对象。
function generator1() {
yield 1;
yield 2;
}
function generator2() {
yield from generator1();
yield 3;
}
foreach (generator2() as $value) {
echo $value . "\n";
}
输出:
1
2
3
生成器非常适合生成无限序列,因为它们只在需要时生成值。
function infiniteSequence() {
$i = 0;
while (true) {
yield $i++;
}
}
$generator = infiniteSequence();
for ($i = 0; $i < 5; $i++) {
echo $generator->current() . "\n";
$generator->next();
}
输出:
0
1
2
3
4
生成器在处理大数据集时非常高效,因为它们不会一次性将所有数据加载到内存中。
function readLargeFile($fileName) {
$file = fopen($fileName, 'r');
while (!feof($file)) {
yield fgets($file);
}
fclose($file);
}
foreach (readLargeFile('largefile.txt') as $line) {
echo $line;
}
这个例子展示了如何逐行读取一个大文件,而不需要将整个文件加载到内存中。
send()
方法生成器可以通过 send()
方法接收外部传入的值。
function generatorWithSend() {
$value = yield;
echo "Received: $value\n";
yield $value * 2;
}
$generator = generatorWithSend();
$generator->send(10); // 输出: Received: 10
echo $generator->current(); // 输出: 20
throw()
方法生成器可以通过 throw()
方法抛出异常。
function generatorWithThrow() {
try {
yield 1;
} catch (Exception $e) {
echo "Caught exception: " . $e->getMessage() . "\n";
}
yield 2;
}
$generator = generatorWithThrow();
$generator->throw(new Exception("Test exception")); // 输出: Caught exception: Test exception
echo $generator->current(); // 输出: 2
return
语句生成器可以使用 return
语句来返回一个最终值。
function generatorWithReturn() {
yield 1;
yield 2;
return 3;
}
$generator = generatorWithReturn();
foreach ($generator as $value) {
echo $value . "\n";
}
echo $generator->getReturn(); // 输出: 3
生成器可以用于实现简单的协程(coroutine),允许在生成器中暂停和恢复执行。
function coroutine() {
$value = yield;
echo "Received: $value\n";
$value = yield;
echo "Received: $value\n";
}
$coroutine = coroutine();
$coroutine->send('Hello');
$coroutine->send('World');
输出:
Received: Hello
Received: World
PHP 生成器提供了一种高效的方式来处理大数据集或需要延迟计算的场景。通过 yield
关键字,生成器可以逐步生成值,而不需要一次性生成所有数据。生成器还可以与 yield from
、send()
、throw()
等方法结合使用,实现更复杂的功能。