PHP Generators

Today we will learn a new topic of generators in PHP in this PHP Generators tutorial.

  • The PHP 5.5 has a good support for generators.
  • It is not a new concept; rather it is a very powerful feature in languages like ruby, C# and python.
  • So it is also used in PHP to provide an easy way to implement iterators.
  • Generators are used to provide an easy way to implement iterators without the overhead or complexity of implementing a class that implements an iterator.
  • Along with this complex task it also allows us to save a lot of memory.
  • If we implement a simple function to return a large number of values, it is defined in such a way that it generates all the values and then returns them at once in an array.
  • But using generators we can return each value at the same time it is generated.
  • For this a generator function and a yield keyword plays a very important role.
  • So let us see what this generator is and how does it work?
  • Working of a generator:
    • To use a generator we define a generator function and return the value from it using a yield keyword.
    • What is this generator function? A generator function is just a simple normal function; but instead of returning a value using normal return statement, it yields (returns) a value using yield statement. It looks like a function but acts like an iterator.
    • What is the task of yield keyword? The yield keyword in a generator function returns the value to the caller of the function. But instead of terminating the function or removing it from stack, it saves its state on the stack and whenever the function is called again it continues from where it was according to the saved state.
    • When actually the generator function is called it returns an object of Generator class which implements an Iterator interface. This object is iterated over again and again till the generator function is repeatedly called.
    • The normal return statement cannot return any value from a generator function, but it can be used without any value to terminate its execution.
    • Let us understand it with an example.
    • We are going to write a generator function to return numbers upto the given range and display them.
    • To demonstrate it, let us create a new folder named generators in the htdocs folder in xampp folder. Then open a new notepad++ document and save it as index.php in this newly created generators folder.
    • Write the following code in index.php file:
    • <?php
      	function nos($l)
      	{
      		for($i=1;$i<=$l;$i++)
      		{
      			yield $i;
      		}
      		return;
      	}
      	
      	echo "<h1>Numbers upto the given range are:</h1>";
      	
      	foreach(nos(10) as $n)
      	{
      		echo $n."<br>";
      	}
      ?>
      
    • In the above code we have written a generator function and have called it in a foreach loop.
    • The generator function nos() has a parameter $l which will be passed to it while calling it.
    • It has a for loop with counter $i having initial value 1 and last value as the value of the parameter.
    • A yield statement returns the value of $i. The return statement is used to terminate the function.
    • The generator function can be called inside the foreach loop as shown below:
    • foreach(nos(10) as $n)
    • When this nos(10) function is called, the value 10 is passed to function nos() and stored in variable $l which is then used in it.
    • Then the counter $i in the for loop is initialized to 1 and 10 is used in place of $l, that means the condition becomes $i<10.
    • Now when value of $i is 1 and the control enters the loop, the yield keyword returns a Generator object with value 1 and displays it.
    • By this time the yield keyword saves the state of the generator function on the stack.
    • After displaying 1, the foreach loop again calls the function nos(). Here, as the state was saved on the stack, the function resumes from where it had stopped i.e. it begins executing the statement after yield statement. Now after yield statement we have the closing curly brace of for loop, so the value of $i is now incremented by 1 and the control after checking the condition again enters the loop. Now $i has value 2 which is yielded using yield statement. It is then displayed in foreach loop.
    • This process continues till the complete generator function is executed.
    • The output is given below:
    • generator_function_output
      fig 1

  • Uses of generators:
    • Generators will be useful in situations where you want a very large number of values to be handled without any complex task of handling iterators.
    • More importantly when you want to display the values and there is no compulsion of storing the values in memory. This saves a lot of memory. For example, reading a file.
  • Receiving values in the generator:
    • Generators not just return values, they can even accept values with the yield keyword.
    • The method send() is used to pass value to the yield. The send() method of the generator object is called with the desired parameter.
    • Let us see an example: If we want our above program with fig 1 to display only first 5 nos. instead of 10, write the following code in index.php file:
    • <?php
      function nos($l)
      	{
      		for($i=1;$i<=$l;$i++)
      		{
      			$e=yield $i;
      			if($e=='end')
      				return;
      		}
      		
      	}
      	
      	echo "<h1>Numbers upto the given range are:</h1>";
      	
      	$no=nos(10);
      	foreach($no as $n)
      	{
      		if($n==5)
      			$no->send('end');
      		echo $n."<br>";
      	}
      ?>
      
    • Here, we will get the output from 1 to 5 only, because we have terminated the generator function after value 5.
    • When the function nos(10) is called in foreach loop, it yields value 1 and saves its state on the stack.
    • The returned value is checked for its equality to value 5. If it is equal, the send() method with some value is called otherwise not. In this case it will not be called.
    • The returned value is displayed using echo statement.
    • Now again the function nos() is called which resumes and starts execution after yield statement.
    • If the send method is executed, the value is accepted by yield statement and stored in the variable $e.
    • It is checked to see if it contains value end, sent by send() method and if it is true the function is terminated using the empty return statement. In our case the function will not be terminated now.
    • It will behave normally till it reaches value 5. Once $i reaches value 5 the send method of the generator object will be called and the generator function will be terminated.
    • The output is shown below:
    • generator_func_terminated_purposefully
      fig 2

    • Thus generators provide a simple way to implement iterators without any complex task and use of minimum memory. This helps programmers to work efficiently with a large data by economic use of memory.

Thus we studied generators in a simple way in this PHP Generators tutorial.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -