X
X

Generator Syntax

We’ve discovered generator functions allow you to pause and give way to other processing providing flexibility in programming. Now lets delve into the syntax to see how to create a simple generator function:

function satNav( ) {
	$distance = 0;
	echo 'Start from driveway.';
	yield '<br/> First Stop.';
	echo '<br/> Take a left.';
	yield '<br/> Second stop sign.';
	echo '<br/> Destination reached.';
	echo '<br/> Your journey was ' . $distance . ' miles.';	
}

When PHP see’s a function containing yield statement’s it automatically knows the function is a generator; or a function that has a broken up execution context.

Now lets invoke the satNav( ) generator function, but when you do you’ll notice nothing happens. No content is echoed out, but why? Whenever you invoke a generator function it actually returns an object, this object will allow you to control what the function executes. You can think of this object as the pedals within your car. It’ll allow you to control the movement of your car; likewise this object will allow you to control the execution of the generator function. So we need to store this object which is our accelerator and brake pedals within a variable:

$controller = satNav( );

Now we’ve stored the returned object in the controller variable. I can point to this variable containing an object giving me control over the execution of the generator function. Here is the official documentation of all the methods that this object contains for controlling your generator function’s:

  • current — Get the yielded value.
  • getReturn — Get the return value of a generator.
  • key — Get the yielded key.
  • next — Resume execution of the generator.
  • rewind — Rewind the iterator.
  • send — Send a value to the generator.
  • throw — Throw an exception into the generator.
  • valid — Check if the iterator has been closed.
  • __wakeup — Serialise callback.

So here’s our generator object or proverbial pedals that’ll allow control of the car or generator function. We mainly want to look at the current and next methods for now. So lets target our generator object and run the current method. We run this method because currently we are at the start of the functions’ execution context, we haven’t actually run any of the commands found in the execution context. Take the following code:

function satNav( ) {
	$distance = 0;
	echo 'Start from driveway.';
	yield '<br> First Stop.';
	echo '<br> Take a left.';
	yield '<br> Second stop sign.';
	echo '<br> Destination reached.';
	echo '<br> Your journey was ' . $distance . ' miles.';
}

$controller = satNav( );

$controller->current( );

Output:

Start from driveway.

The $distance variable has been created but we cannot see it outputted; we can however see the next command that has been executed, the echo statement. We are now at the first yield sign and the current method returns the yielded value, in our case the string ‘<br> First Stop.’ But this hasn’t been outputted to the browser because we haven’t told it too. Well now we know that string is being returned by the current method we can just echo it out:

echo $controller->current( );

Output:

Start from driveway.
First stop.

Now we’re at that stop sign what happens when we run the same current method. Well the current method executes from the current position which previously was the beginning of the execution context. Now however we are at the first stop or yield sign so this is our current position; if I run the current method and keep running the current method we’re just going to stay in the same place like so:

echo $controller->current( );
echo $controller->current( );
echo $controller->current( );
echo $controller->current( );

Output:

Start from driveway.
First stop.
First stop.
First stop.
First stop.

So we just stay at the current position or at the current yield statement. How do we now step on the accelerator and continue executing commands? In order to do that we need the next method, this method will allow us to continue and run the next set of commands till either the next yield sign or until we reach the end of the function. Lets step on the accelerator or invoke the next method now:

echo $controller->current( );
$controller->next( );

Output:

Start from driveway.
First stop.
Take a left.

The satNav function again echoed ‘Take a left.’ but it yielded the string value ‘Second stop sign.’ it didn’t however print this string out. Note the ‘->next( )’ method returns nothing unlike the ‘->current( )’ method which returned the yielded value. So we have to use the current method again to fetch the yield value:

echo $controller->current( );
$controller->next( );
echo $controller->current( );

Output:

Start from driveway.
First stop.
Take a left.
Second stop sign.

So by using the current method after the next method we returned the yielded string value ‘Second stop sign.’ and echoed it out. Now to complete the process of the entire generator function and execute the last two commands we again need to push the accelerator pedal which is the next method:

echo $controller->current( );
$controller->next( );
echo $controller->current( );
$controller->next( );

Output:

Start from driveway.
First stop.
Take a left.
Second stop sign.
Destination reached.
Your journey was 0 miles.

So this next function allowed our generator’s execution context to finish and complete all processes. When our generator is stopped or waiting at a yield sign the PHP compiler is free todo other tasks. Now we can even take returned string values and analyse them:

function satNav( ){

	$distance = 0;
	echo 'Start from driveway.';
	yield '<br> First Stop.';
	
	echo '<br> Take a left.';
	yield '<br> Second stop sign.';
	
	echo '<br> Destination reached.';
	echo '<br> Your journey was ' . $distance . ' miles.';
}


$control = satNav();

$val = $control->current();
echo $val . ' concat 123';
echo '<br> <br> <br> <br>';

$control->next();

echo $control->current();

$control->next();

You can see I’ve put in bold the assignment of the first yielded value and two echo statements. These commands are outside the the generator function but now notice the output of the code:

Start from driveway.
First Stop. concat 123




Take a left.
Second stop sign.
Destination reached.
Your journey was 0 miles.

So after the first current method ran you’ll notice the string ‘First Stop.’ was yielded and assigned to the $val variable. We then concatenated the string ‘concat 123’ onto the end of the string and echoed it out. Then we had another echo command to output four line breaks. You can see that our generator function paused and waited for our assignment and two echo statement’s we’re finished. Then we carried on executing the function. This is only very basic and we’re just scratching the surface here but there is much more to learn; please go to the next lecture to find out more about generators.

Latest Posts