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;
}

 上述列子在运行到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) . '<br />';
}

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值