Follow the instructions in the PHP documentation
A generator function looks like a normal function, unlike a normal function that returns a value, and a generator can yield many of the values it needs.
When a generator is called, it returns an object that can be traversed. When you traverse this object (for example, through a foreach loop), PHP will call the generator function every time a value is needed and save the generator state after a value is generated. This allows it to revert to the calling state when it needs to produce the next value.
Once you no longer need to generate more values, the generator function can simply exit, and the code that calls the generator can continue to execute as if an array has been traversed.
A generator can not return a value: Doing so produces a compilation error. However, return null is a valid syntax and it will terminate the generator to continue execution.
/** * The original writing, I need a way to organize the data. Nums () returns an array or other data that can be iterated * and then iterates through the array*/functionnums () {$array=Array(); for($i= 0;$i< 10000; ++$i) { $array[]=$i; } return $array;}foreach(Nums () as $v){ Var_dump($v);};/** * But after using yield, I no longer need to create a variable to store this data. * Instead, the generated value is internally paired with a contiguous integer index, just like a non-associative array. * This saves a lot of memory overhead*/functionNums2 () { for($i= 0;$i< 10000; ++$i) {yield$i; }}foreach(NUMS2 () as $v){ Var_dump($v);};
$handler=function() { $start=Microtime(true); Yield $use _time= (Microtime(true) -$start) * 1000; Echo"The time is". (int)$use _time." Ms\n "; Yield $use _time= (Microtime(true) -$start) * 1000; Echo"The Time2 is". (int)$use _time." Ms\n ";};//according to the documentation, when a generator is called, it returns an object that can be traversed. When you traverse this object, the//php will call the generator function every time the value is needed,//that is, the function defined in $handler is not actually called at this time. Instead, it returns a generator$generator=Call_user_func_array($handler,Array());if($generator&&$generatorinstanceof \generator) { //The function defined in the $handler is actually called when the generator is iterated. if($generator- Current() ===false) { /***do some thing**/ }}
The generator can also be referenced to use the
/** * Use references to generate values*/function&gen_reference () {$value= 3; while($value> 0) {yield$value; }}/** We can modify the value of the number in the loop, and the generator is used to generate the reference value, so the $value value inside the gen_reference () will also change. */foreach(Gen_reference () as&$number) { Echo(--$number).‘ ... ‘;}
In addition to changing the data in the generator by reference, we can also use the Send method to pass the data
function printer () { while (true) { $string =$string;}} $printer = printer (); $printer->send (' Hello world! ');
However, if the above example does not have a while (true), the generator executes only once, no matter how many times the subsequent send. So, it seems that this can be used to control the maximum number of times this function is called?
In addition to passing data inside, you can throw exceptions.
functionapplication () { while(true){ Try { yield; }Catch(Exception $e){ Echo $e; } }}$printer= application();$printer-Throw(New Exception("Test"));
Nesting of generators
/** * can be nested in PHP7 by yield from*/functionCount_to_ten () {yield1; Yield2; Yield from [3, 4]; Yield fromNewArrayiterator ([5, 6]); Yield from seven_eight (); Yield9; Yield10;}functionseven_eight () {yield7; Yield from eight ();}functionEight () {yield8;}$gen=Count_to_ten ();foreach($gen as $num) { Echo"$num";}Echo"The return value is".$gen->getreturn ();
Use of the PHP generator