minte9
LearnRemember



Yield values

A generator function looks like a normal function, except of returning a value. It yields as many values as it needs to.
 
function myGenerator()
{
    for ($i=1; $i<=3; $i++) {
        yield $i;
    }
}
Generator class is implementing Iterator interface. You have to loop over to get values.
 
function myGenerator()
{
    for ($i=1; $i<=3; $i++) {
        yield $i;
    }
}

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

// Outputs: 1 2 3

Yield doesn't stop the execution of the function and returning, Yield provides a value and pause the execution of the function.

Examples

This is an example without generator (bad).
   code
// bad example

function makeRange($length)
{
    $data = array();

    $i = 0;
    while( $i++ < $length) <span class='keyword_code'>$data[]</span> = $i;

    echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. "<br>";

    return $data;
}

foreach(makeRange(1000000) as $v) {} // 32.38 MB

foreach(makeRange(3000000) as $v) {} // Allowed memory exhausted
This is how generators save memory (good).
 
// yield example

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

    echo round(memory_get_usage() / 1024 / 1024, 2) . ' MB'. "<br>";
}

foreach(makeRange(1000000) as $v) {} // 0.37 MB

foreach(makeRange(3000000) as $v) {} // 0.37 MB
Big files example,
 
function makeFile() {

    if ($fd = fopen("generators.txt", "w+")) {

        $i = 0;
        while($i++ < 10000000) { // <span class='keyword_code'>128 MB</span> allowed in php
            fwrite($fd, $i . " GGG <br>");
        }

        fclose($fd);
    }
}

//makeFile(); // <span class='keyword_code'>152 MB</span> generators.txt

function getRows() {

    if ($fd = fopen("generators.txt", "rb")) {

        while (!feof($fd)) {
            <span class='keyword_code'>yield</span> fgets($fd, 4096);
        }
    }
}

function getRowsArray() {

    $data = array();

    if ($fd = fopen("generators.txt", "rb")) {

        while (!feof($fd)) {
            <span class='keyword_code'>$data[]</span> = fgets($fd, 4096);
        }
    }

    return $data;
}

// yield
foreach(getRows() as $v) {} echo "<span class='keyword_code'>it works with yield</span>";

// array
foreach(getRowsArray() as $v) {}
    // Allowed memory size of 134217728 bytes <span class='keyword_code'>exhausted</span>



  Last update: 303 days ago