X
X

PHP7 Generator new features

Firstly lets look at return statements which in a generator function must be the last statement within the generator function. So for example…

function gen( ){
	yield 100;
	yield 200;
	yield 300;
	return 400;
}

… Now we want to run our execution context without the use the next and current method’s, instead we want to use the foreach loop to continue automate the execution of the context.

$control = gen( );

foreach( $control as $value ){
	echo '<br>' . $value;
}

… This will produce the following output…

100
200
300

However up until this point everything that has been shown is nothing new to PHP generators which’ve been around since version 5.5; so what’s new? Well we can now have return statements and we can use the yield from statement on callable generator objects. Don’t forget in PHP, functions are first class citizens or callable objects meaning we can treat them as objects in our program.

So the for loop has run through all of the stop or yield signs and successfully yielded each value. However the return statement has not been printed out, that is because we are automating the stop and go process or current and next method’s. However once we’ve finished the journey we can then use the getReturn() method to fetch the last value and echo it out. Like so…

$control->getReturn();

… This will produce…

400

… Note if you try this script …

$control = gen( );

$control->getReturn( );

foreach( $control as $value ){
	echo '<br>' . $value;
}

… It would error because we have ran getReturn before we have gone through all of the stop signs. Which is like going from the start of the execution to the end excluding the entire journey. This won’t work as you know you can’t just hop in your car and then get out again expecting to be at your destination without the journey, the same applies here.

Finally we also have the ability to yield to other stop signs from other callable generator functions. Think of this like importing those stop signs or yield statements from another generator function or callable object…

function gen( ){
	 yield from gen2( );
	yield 100;
	yield 200;
	yield 300;
	return 400;
}

function gen2( ){
	yield 10;
	yield 20;
	yield 40;
	yield 80;
}

… Running the gen function in a foreach loop like so…

$control = gen( );

foreach( $control as $value ){
	echo '<br>' . $value;
}

$control->getReturn( );

… Will output…

10
20
40
80
100
200
300
400

… Effectively we have imported the execution context from one generator, gen2, into the first generator function gen. You could think of it like this…

function gen( ){
	yield 10;
	yield 20;
	yield 40;
	yield 80;
	yield 100;
	yield 200;
	yield 300;
	return 400;
}

… Also it’ll import any command in the execution context not just yield statements for example…

function gen( ){
	 yield from gen2( );
	yield 100;
	yield 200;
	yield 300;
	return 400;
}

function gen2( ){
	echo 'hello world';
	yield 10;
	echo 2 + 2;
	yield 20;
	echo 'That's it!';
	yield 40;
	echo ( 2 + 2 ) * 5;
	yield 80;
}

… All the execution context will be imported from gen2 into gen…

function gen( ){
	echo 'hello world';
	yield 10;
	echo 2 + 2;
	yield 20;
	echo 'That's it!';
	yield 40;
	echo ( 2 + 2 ) * 5;
	yield 80;
	yield 100;
	yield 200;
	yield 300;
	return 400;
}

… You can also import as many commands as you’d like from a range of generator functions…

function gen( ){
	 yield from gen2( );
	yield 100;
	yield 200;
	yield 300;
	 yield from gen3( );
	return 400;
}

function gen2( ){
	echo 'hello world';
	yield 10;
	echo 2 + 2;
	yield 20;
}

function gen3( ){
	echo 'That's it!';
	yield 40;
	echo ( 2 + 2 ) * 5;
	yield 80;
}

… This example would be like…

function gen( ){
	echo 'hello world';
	yield 10;
	echo 2 + 2;
	yield 20;
	yield 100;
	yield 200;
	yield 300;
	echo 'That's it!';
	yield 40;
	echo ( 2 + 2 ) * 5;
	yield 80;
	return 400;
}

You can keep going in this fashion and import as many commands or execution contexts as you’d like from a whole range of generator functions. Hopefully that now helps in understanding generator functions. You can see in PHP7 plus there is a lot to play with in the functional programming paradigm.

Latest Posts