ehough/generators

此包已废弃且不再维护。未建议替代包。

模拟 PHP 5.3 和 5.4 中的生成器。用于代码回滚。

v1.0.0 2016-12-23 20:33 UTC

This package is not auto-updated.

Last update: 2020-04-03 18:01:40 UTC


README

Build Status Code Coverage Scrutinizer Code Quality Latest Stable Version License

轻松将 生成器 回滚到 PHP 5.3 和 5.4。

已废弃

现在大多数 PHP 安装已原生支持生成器,因此此库已过时。

为什么?

此库可以(相对)轻松地将依赖生成器的代码回滚到旧系统(PHP < 5.5)。如果你不需要将代码回滚到 PHP 5.3 或 5.4,则不需要此库。

快速开始

假设你需要在 PHP 5.3 上使用以下代码

$generator = function ($values) {
    print "Let's get started\n";
    foreach ($values as $key => $value) {
        yield $key => $value;
    }
    print "Nothing more to do\n";
};

$items = array('foo' => 'bar', 'some' => 'thing');

foreach ($generator($items) as $k => $v) {
    print "The generator gave us $k => $v\n";
}

上面的代码结果为

Let's get started
The generator gave us foo => bar
The generator gave us some => thing
Nothing more to do

由于上面的代码使用了生成器,它无法在 PHP 5.4 或更低版本上运行。此库提供给您一个 AbstractGenerator 类,该类要求您实现 resume($position)$position 在生成器每次恢复执行时递增,您可以使用此位置来确定要运行生成器的哪个部分。因此,上述生成器可以被重写为

use Hough\Generators\AbstractGenerator

class MyGenerator extends \Hough\Promise\AbstractGenerator
{
    private $keys;
    private $values;

    public function __construct(array $items)
    {
        $this->keys   = array_keys($items);
        $this->values = array_values($items);
    }

    protected function resume($position)
    {
        // first execution
        if ($position === 0) {
            print "Let's get started\n";
        }

        // still inside the for loop
        if ($position < count($this->values)) {

            // return an array of two items: the first is the yielded key, the second is the yielded value
            return array(
                $this->keys[$position],
                $this->values[$position]
            );
        }

        // we must be done with the for loop, so print our last statement and return null to signal we're done
        print "Nothing more to do\n";
        return null;
    }
}

$items = array('foo' => 'bar', 'some' => 'thing');
foreach (new MyGenerator($items) as $k => $v) {
    print "The generator gave us $k => $v\n";
}

上面的代码结果为

Let's get started
The generator gave us foo => bar
The generator gave us some => thing
Nothing more to do

代码并不那么整洁简单,但任何生成器都可以使用此库重写。

生成键和值

resume($position) 返回的内容你有三种选择

  1. 如果你返回 null,表示生成器内部没有更多的语句。此时,生成器将被视为关闭。
  2. 如果你返回一个包含两个值的数组,第一个元素被解释为生成的键,第二个值为生成的值。
  3. 如果你返回一个包含一个值的数组,它被解释为生成的值,而 $position 将用作键。

访问发送的值

你可以使用 getLastValueSentIn() 访问从调用者发送的最后一个值。这可能为 null

处理异常

默认情况下,如果生成器内部抛出异常(通过 throw(\Exception $e)),它将被重新抛回到调用上下文。如果你想“捕获”这些异常,你可以覆盖 onExceptionThrownIn(\Exception $e) 并吞或以其他方式处理异常。