1.PHP迭代器
当我们使用foreach时,每次迭代都会将当前的元素的值赋给$value并将数组的指针移动指向下一个元素为下一次迭代做准备,从而实现顺序遍历。像这样能够让外部的函数迭代自己内部数据的接口就是迭代器接口,对应的那个被迭代的自己就是迭代器对象。
- 1 Iterator接口
Iterator接口扩展了Traversable接口,Traversable是一个空接口,它相当于一个标志,所有实现Iterator接口的类肯定也实现了Traversable接口
““
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)
}
““
- 2 Generator类
Generator提供了一种方便的实现简单的Iterator(迭代器)的方式,使用Generator实现Iterator不需要创建一个类来继承Iterator接口。
Generator implements Iterator {
/* Methods */
public mixed current ( void )
public mixed key ( void )
public void next ( void )
public void rewind ( void )
public mixed send ( mixed $value )
public mixed throw ( Exception $exception )
public bool valid ( void )
public void __wakeup ( void )
}
它实现了Iterator中的5个方法,还提供了三个新方法,其中__wakeup是一个魔术方法,用于序列化,Generator实现这个方法是为了防止序列化。另外两个新方法是throw和send,
- 迭代器实例
““
2.生成器
相比较迭代器,生成器提供了一种更容易的方法来实现简单的对象迭代,性能开销和复杂性都大大降低。
一个生成器函数看起来像一个普通的函数,不同的是普通函数返回一个值,而一个生成可以yield生成许多它所需要的值,并且每一次的生成返回值只是暂停当前的执行状态,当下次调用生成器函数时,PHP会从上次暂停的状态继续执行下去。
(迭代)生成器也是一个函数,不同的是这个函数的返回值是依次返回,而不是只返回一个单独的值.或者,换句话说,生成器使你能更方便的实现了迭代器接口.
介绍之前首先看一个例子如果现在要求我们输出1-1000000之前的所有的数字我们应该怎么输出 ?同时我们监控下内存的使用
<?php
echo "foreach start time:", time(), "\n";
echo "foreach start memory:", memory_get_usage(), "\n";
foreach (range(1, 1000000) as $num) {
echo $num, "\n";
}
echo "foreach end time:", time(), "\n";
echo "foreach end memory:", memory_get_usage(), "\n";
执行下输出:
[root@centos-linux work]# php yield.php
foreach start time:1508082920
foreach start memory:227400
PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 32 bytes) in /media/psf/www/work/yield.php on line 4
信息显示,php.ini中的内存分配的问题,默认php代码能够申请到的最大内存字节数就是134217728 bytes,如果代码执行的时候再需要更多的内存,就会报错了。如果想要顺利执行怎么办?
修改php.ini中memory_limit = 256M
PHP代码中执行前添加set_time_limit(256M);
当然修改扩大申请内存的不是我们主要讲的。这时候我们可以使用生成器,代码如下:
““