PHP入门很轻松(微课超值版)
上QQ阅读APP看书,第一时间看更新

4.6.2 生成器与数组的区别

生成器允许在foreach代码块中写代码来迭代一组数据,而不需要在内存中创建一个数组,如果数据很大,会使内存达到上限,或者会占据很长的处理时间。生成器对PHP应用的性能有很大的提升,运行代码时也可以节省大量的内存,同时生成器也适合计算大量的数据。

创建一个数组来存放迭代的数据。具体的步骤如下:

(1)先创建一个create()函数。create()函数是一个常见的PHP函数,在处理一些数组时经常会使用到。

(2)create()函数内包含一个for循环,循环会把当前时间放到数组($data)里面。

(3)for循环执行完毕,把$data返回出去。

(4)调用create()函数,并传入一个参数值,赋值为$result。

(5)使用foreach循环遍历$result。

【例4-23】数组迭代数据(实例文件:源文件\ch04\4.23.php)。

运行结果如图4-24所示。

图4-24 数组迭代数据

在这个实例中,给函数传的值是8,假如是1000万呢?那么create()函数中,for循环就需要执行1000万次,且有1000万个值被放到数组中,而数组再被放入到内存中,所以在调用函数时会占用大量的内存。

下面来看一下使用生成器迭代数据。

这里直接修改上面的代码,删除数组$data,而且也没有返回任何内容,而是在time()之前使用了一个关键字yield,其他的不变。

【例4-24】生成器迭代数据(实例文件:源文件\ch04\4.24.php)。

运行结果如图4-25所示。

图4-25 生成器迭代数据

上面的结果和第一次没有使用生成器输出的结果不一样,这里的值中间间隔了1秒(sleep(1)造成的)。但是第一次没有时间间隔,那是因为create()函数内的for循环结果被很快放到$data中,并且立即返回,所以,这里的foreach循环是一个固定的数组。使用生成器时,create()函数的值不是一次性快速生成,而是依赖于foreach循环,foreach循环一次,for执行一次。

生成器的执行过程如下:

(1)调用create()函数,传入参数值8,但是for循环执行了一次然后停止,并且告诉foreach第一次循环可以用的值。

(2)foreach开始对$result循环,进来首先sleep(1),然后开始使用for循环给的一个值执行输出。

(3)foreach准备第二次循环,开始第二次循环之前,它向for循环又请求了一次。

(4)for循环于是又执行了一次,将生成的时间戳告诉foreach。

(5)foreach拿到第二个值,并且输出,由于foreach中有sleep(1),所以for循环延迟了1秒生成当前时间。

可以发现,整个代码执行中,始终只有一个记录值参与循环,内存中也只有一条信息。

无论开始传入的$number有多大,由于并不会立即生成所有结果集,所以内存始终是一条循环的值。