面试-PHP篇-yield

yield生成器是php5.5之后出现的,yield提供了一种更容易的方法来实现简单的迭代对象,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低。

yield生成器允许你 在 foreach 代码块中写代码来迭代一组数据而不需要在内存中创建一个数组。

对比:

function gettime($num) {
    $data=[];
    for($i=0;$i<$num;$i++) {
        $data[] = time();
    }
    return $data;
}

foreach (gettime(3) as $v) {
    echo $v.PHP_EOL;
    sleep(1);
}

//输出结果如下:
1577710522
1577710522
1577710522

使用迭代器yield:

function gettime($num) {
    for($i=0;$i<$num;$i++) {
        yield time();
    }
}

foreach (gettime(3) as $v) {
    echo $v.PHP_EOL;
    sleep(1);
}
//输出结果如下
1577710705
1577710706
1577710707


 

对比结果发现。使用yield生成的结果是在,被外部调用时才生成。数据不是存于数组中,而是每被调用一次生成一个数据。在处理大数据是,可以明显减少内存的使用

 实际的应用场景

1.读取超大文件

header("content-type:text/html;charset=utf-8");
function readTxt()
{
    $handle = fopen("./test.txt", 'rb');

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

    fclose($handle);
}

foreach (readTxt() as $key => $value) {
    # code...
    echo $value.'<br />';
}

2.处理超大数据

如:求k的次方相加
k0+k1+k2+……+kn

 

function squares($k, $n) {
    static $res=1;
    for ($i=0;$i<$n;$i++){
        yield $res *= $k;
    }
}

$num =1;
foreach (squares(2,1000) as $v) {
    $num += $v;
}
echo $num;die;

yield输出的键值对

function squares($start, $stop) {
    if ($start < $stop) {
        for ($i = $start; $i <= $stop; $i++) {
            yield $i => $i * $i;
        }
    }
    else {
        for ($i = $start; $i >= $stop; $i--) {
            yield $i => $i * $i; //迭代生成数组: 键=》值
        }
    }
}
foreach (squares(3, 5) as $n => $square) {
    echo $n . ' squared is ' . $square .PHP_EOL;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章