php (生成器)

 php 生成器(generator)是php5.5引入的功能,往往没被充分利用,其实这是非常有用的功能,
 我相信很多的php开发者都不知道生成器,因为生成器的作用不是很明显,生成器是简单的迭代器,仅此而已。

 与标准的php迭代器不同,php生成器不要求类实现 Iterator接口,从而减轻了类的负担,生成器会根据需求
 计算并产出要迭代的值,这对应用的性能有重大的影响,试想一下。假如标准的php迭代器经常在内存中执行迭代
 操作,这要预先计算出数据集,性能低下,如果使用特定的方式计算大量数据,对性能的影响更甚,此时我们可以
 使用生成器,及时计算产出的续值,不占用宝贵的内存资源。
php生成器不能满足所有的迭代操作的需求,因为如果不查询,生成器永远不知道下一个要迭代的值是什么,在
生成器中无法后退或快进,生成器还是一次性的,无法多次迭代同一个生成器,不过,如果需要,可以重建或克隆
生成器。

 一个简单的生成器

function myGenerator()
{
    yield 'value1';
    yield 'value2';
    yield 'value3';
}

foreach (myGenerator() as $yieldedValue) {
    echo $yieldedValue . PHP_EOL;
}

结果  value1 value2 value3

生成一个范围内的数值(错误的做法)

function makeRange($length)
{
    $dataset = [];
    for($i = 0; $i < $length; $i++) {
        $dataset[] = $i;
    }

    return $dataset;
}

$customRange = makeRange(1000000);

foreach ($customRange as $i) {
    echo $i . PHP_EOL;
}

 上述的makeRange() 函数需要为预先创建一个由一百万个整数组成的数组分配内存,php生成器能实现相同的操作,不过一次只会为了一个整数分配内存。

如果把makeRange()中的数字改为 100000000 则会报以下错误,说明了一次需要生成所有的内存。就会包以下的错误

生成一个范围内的数值(正确的做法)

function makeRange($length)
{
    for($i = 0; $i < $length; $i++) {
        yield $i;
    }
}

foreach (makeRange(10000000) as $i) {
    echo $i . PHP_EOL;
}

php (生成器)_第1张图片

 上述列子在运行到1057492 以后才会报内存相关的错误问题,证明了生成器一次只会为了一个整数分配内存,良好的减少了内存的使用。

 这是一个虚拟的列子,假设我们想迭代一个大小为4GB的 CSV 文件,而虚拟机的私有服务器只允许php使用1GB的内存,因此不能把整个文件都加载到内存中,下面的例子使用生成器完成了这种操作

function getRows($file)
{
    $handle = fopen($file, 'rb');

    if ($handle === false) {
        throw new Exception();
    }

    while (feof($handle) === false) {
        yield fgetcsv($handle);
    }

    fclose($handle);
}

foreach (getRows('data.csv') as $row) {
    print_r($row) . '
'; }

你可能感兴趣的:(php笔记,php,(Modern)笔记)