在讲解生成器之前,先介绍一下迭代器:在PHP中,通常使用foreach来遍历数组。如果我们想让一个对象可遍历怎么办?PHP为我们提供了Iterator接口。只要实现了这个接口,就可以通过foreach迭代这个对象。一个例子如下:classmyIteratorimplementsIterator{private$index=0;私人$数据='';公共函数__construct($data){$this->index=0;$this->data=$data;}functionrewind(){$this->index=0;}functioncurrent(){return$this->data[$this->index];}functionkey(){return$this->index;}functionnext(){++$this->index;}functionvalid(){returnisset($this->data[$this->index]);}}$it=newmyIterator(array("hello","php","iterator",));foreach($itas$key=>$value){echo"$key:$value
";当我们通过foreach遍历$it时,PHP会依次调用:rewind()reset到第一个元素valid()检查当前位置是否有效current()返回当前元素key()返回当前的keyelementnext()指向下一个元素生成器是PHP5.5引入的新特性,不过目前好像很少有人用。我们试试PHP官方文档中对generator的解释:generatorsprovideaneasierwaytoimplementsimpleobjectiteration。与定义实现Iterator接口的类相比,性能开销和复杂度大大降低。生成器允许您在foreach块中编写代码以迭代一组数据,而无需在内存中创建数组,这会达到内存限制或占用大量处理时间。相反,您可以编写一个生成器函数,就像普通的自定义函数一样,而不是只返回一次,生成器可以根据需要多次生成需要迭代的值。为了体现生成器的优势,我们定义一个函数进行比较:functionfunc1(){foreach(range(0,1000000)as$value){echo$value;}}func1();//(!)Fatalerror:Allowedmemorysizeof134217728bytesexhausted(triedtoallocate402653192bytes)inxxx.phponline5因为在内存中创建和迭代这么大的数组,PHP直接提示超出了单个进程的内存限制。让我们将其更改为生成器:functionfunc1(){foreach(range(0,1000000)as$value){yield$value;}}var_dump(func1());//object(Generator)[1]foreach(func1()as$value){echo$value;}可以看到我们调用func1()返回了一个Generator对象,可以通过foreach对其进行迭代。对于每次迭代,PHP都会要求Generator实例计算并提供以下A值进行迭代。生成器的优雅体现在每一个值产生后,生成器内部状态都会暂停;当从生成器请求下一个值时,将恢复内部状态。生成器内部的状态将在暂停和恢复之间切换,直到到达函数定义主体的末尾或遇到空的return语句。参考链接:https://laravalalacademy.org/po...http://php.net/manual/zh/lang...
