多数大学生出来选择的工作和专业无关
首页 > 专业知识

PHP的生成器、yield和协程之间关系

时间:2019-01-26 17:33:23 [来源]:郑州PHP培训学校

  PHP的生成器、yield和协程之间关系

在了解生成器之前我们先来看一下迭代器和迭代。迭代是指反复执行一个过程,每执行一次叫做迭代一次。比如普通的遍历便是迭代:
 
$arr = [1, 2, 3, 4, 5];
 
foreach($arr as $key => $value) {
    echo $key . ' => ' . $value . "\n";
}
我们可以看到通过foreach对数组遍历并迭代输出其内容。在foreach内部,每次迭代都会将当前的元素的值赋给$value并将数组的指针移动指向下一个元素为下一次迭代坐准备,从而实现顺序遍历。像这样能够让外部的函数迭代自己内部数据的接口就是迭代器接口,对应的那个被迭代的自己就是迭代器对象。
 
PHP提供了统一的迭代器接口:
 
Iterator extends Traversable {
 
    // 返回当前的元素
    abstract public mixed current(void)
    // 返回当前元素的键
    abstract public scalar key(void)
    // 向下移动到下一个元素
    abstract public void next(void)
    // 返回到迭代器的第一个元素
    abstract public void rewind(void)
    // 检查当前位置是否有效
    abstract public boolean valid(void)
}
通过实现Iterator接口,我们可以自行的决定如何遍历对象。比如通过实现Iterator接口我们可以观察迭代器的调用顺序。
 
 
class MyIterator implements Iterator {
    private $position = 0;
    private $arr = [
        'first', 'second', 'third',
    ];
    
    public function __construct() {
        $this->position = 0;
    }
    
    public function rewind() {
        var_dump(__METHOD__);
        $this->position = 0;
    }
    
    public function current() {
        var_dump(__METHOD__);
        return $this->arr[$this->position];
    }
    
    public function key() {
        var_dump(__METHOD__);
        return $this->position;
    }
    
    public function next() {
        var_dump(__METHOD__);
        ++$this->position;
    }
    
    public function valid() {
        var_dump(__METHOD__);
        return isset($this->arr[$this->position]);
    }
    
}
 
$it = new MyIterator();
 
foreach($it as $key => $value) {
    echo "\n";
    var_dump($key, $value);
}
通过这个例子能够清楚的看到了foreach循环中调用的顺序。从例子也能看出通过迭代器能够将一个普通的对象转化为一个可被遍历的对象。这在有些时候,能够将一个普通的UsersInfo对象转化为一个可以遍历的对象,那么就不需要通过UsersInfo::getAllUser()获取一个数组然后遍历数组,而且还可以在对象中对数据进行预处理。
 
yield和生成器
相比较迭代器,生成器提供了一种更容易的方法来实现简单的对象迭代,性能开销和复杂性都大大降低。
 
一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成可以yield生成许多它所需要的值,并且每一次的生成返回值只是暂停当前的执行状态,当下次调用生成器函数时,PHP会从上次暂停的状态继续执行下去。
 
我们在使用生成器的时候可以像关联数组那样指定一个键名对应生成的值。如下生成一个键值对与定义一个关联数组相似。
 
 
function xrange($start, $limit, $step = 1) {
    for ($i = $start, $j = 0; $i <= $limit; $i += $step, $j++) {
        // 给予键值
        yield $j => $i;
    }
}
 
$xrange = xrange(1, 10, 2);
foreach ($xrange as $key => $value) {
    echo $key . ' => ' . $value . "\n";
}

上一篇:恰当应用函数实现PHP获取表字段名

下一篇:PHP获取字段长度相关函数使用技巧