PHP 5.6生成器语法:只能在foreach循环中使用生成器吗?

时间:2015-04-15 06:51:50

标签: php generator

我知道如果没有发电机,这可以超级轻松地实现,但我想更好地了解发电机。因此,请不要建议使用其他东西。


我有一个为截图(selenium)生成文件名的类:

class ScreenshotName
{

    private $counter = 0;

    public function screenshotNameIterator()
    {
         while(true) {
            yield sprintf("screenshot-%s-%s.png", date("Y-m-d\\TH:i:s"), ++$this->counter);
        }
    }
}

现在我的问题是:我可以在foreach循环之外的任何其他上下文中使用这样的生成器吗?例如

(new ScreenshotName())->screenshotNameIterator()->next()

对我来说,这总是返回null,如果我调试,它永远不会进入生成器方法。 PHP文档也没有真正提到这一点。

所以我的问题是:有一种文档化的方式在不同于for循环的上下文中使用生成器吗?

2 个答案:

答案 0 :(得分:2)

有记录的方法可以做到这一点。事实上,Generator确实实现了迭代器接口,你可以在page上看到它。

实际上foreach关键字仅适用于迭代器。因此,如果您可以在生成器上使用foreach,则必须能够调用next

以下是使用next代替foreach的示例代码:

<?php

function evenNumbers() {
    for ($i = 0;; $i++) {
        yield 2*$i;
    }
}

$gen = evenNumbers();
$gen->next();
echo $gen->current();

?>

答案 1 :(得分:0)

以下是Dark Duck's answer附带的完整代码段。也就是说,它演示了如何使用Iterator接口迭代所有值。 (Duck Duck的代码不完整。)基于a comment by robert_e_lee on Iterator doc

$gen = evenNumbers();
// If in a method that re-uses an iterator, may want the next line.
//OPTIONAL $gen->rewind();
while ($gen->valid()) {
    // This is the value:
    $value = $it->current();
    // You might or might not care about the key:
    //OPTIONAL $key = $it->key();

    // ... use $value and/or $key ...

    $it->next();
}

以上内容大致等同于:

foreach (evenNumbers() as $value) {
    // ... use $value ...
}

foreach (evenNumbers() as $key => $value) {
    // ... use $value and/or $key ...
}