<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <title>Generators overview</title> </head> <body><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="language.generators.html">Generators</a></div> <div class="next" style="text-align: right; float: right;"><a href="language.generators.syntax.html">Generator syntax</a></div> <div class="up"><a href="language.generators.html">Generators</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div><hr /><div id="language.generators.overview" class="sect1"> <h2 class="title">Generators overview</h2> <p class="verinfo">(PHP 5 >= 5.5.0)</p> <p class="para"> Generators provide an easy way to implement simple <a href="language.oop5.iterations.html" class="link">iterators</a> without the overhead or complexity of implementing a class that implements the <a href="class.iterator.html" class="classname">Iterator</a> interface. </p> <p class="para"> A generator allows you to write code that uses <a href="control-structures.foreach.html" class="link">foreach</a> to iterate over a set of data without needing to build an array in memory, which may cause you to exceed a memory limit, or require a considerable amount of processing time to generate. Instead, you can write a generator function, which is the same as a normal <a href="functions.user-defined.html" class="link">function</a>, except that instead of <a href="functions.returning-values.html" class="link">return</a>ing once, a generator can <a href="language.generators.syntax.html#control-structures.yield" class="link">yield</a> as many times as it needs to in order to provide the values to be iterated over. </p> <p class="para"> A simple example of this is to reimplement the <span class="function"><a href="function.range.html" class="function">range()</a></span> function as a generator. The standard <span class="function"><a href="function.range.html" class="function">range()</a></span> function has to generate an array with every value in it and return it, which can result in large arrays: for example, calling <strong class="command">range(0, 1000000)</strong> will result in well over 100 MB of memory being used. </p> <p class="para"> As an alternative, we can implement an <em>xrange()</em> generator, which will only ever need enough memory to create an <a href="class.iterator.html" class="classname">Iterator</a> object and track the current state of the generator internally, which turns out to be less than 1 kilobyte. </p> <div class="example" id="example-274"> <p><strong>Example #1 Implementing <span class="function"><a href="function.range.html" class="function">range()</a></span> as a generator</strong></p> <div class="example-contents"> <div class="phpcode"><code><span style="color: #000000"> <span style="color: #0000BB"><?php<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">xrange</span><span style="color: #007700">(</span><span style="color: #0000BB">$start</span><span style="color: #007700">, </span><span style="color: #0000BB">$limit</span><span style="color: #007700">, </span><span style="color: #0000BB">$step </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">) {<br /> if (</span><span style="color: #0000BB">$start </span><span style="color: #007700">< </span><span style="color: #0000BB">$limit</span><span style="color: #007700">) {<br /> if (</span><span style="color: #0000BB">$step </span><span style="color: #007700"><= </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br /> throw new </span><span style="color: #0000BB">LogicException</span><span style="color: #007700">(</span><span style="color: #DD0000">'Step must be +ve'</span><span style="color: #007700">);<br /> }<br /><br /> for (</span><span style="color: #0000BB">$i </span><span style="color: #007700">= </span><span style="color: #0000BB">$start</span><span style="color: #007700">; </span><span style="color: #0000BB">$i </span><span style="color: #007700"><= </span><span style="color: #0000BB">$limit</span><span style="color: #007700">; </span><span style="color: #0000BB">$i </span><span style="color: #007700">+= </span><span style="color: #0000BB">$step</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">yield $i</span><span style="color: #007700">;<br /> }<br /> } else {<br /> if (</span><span style="color: #0000BB">$step </span><span style="color: #007700">>= </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br /> throw new </span><span style="color: #0000BB">LogicException</span><span style="color: #007700">(</span><span style="color: #DD0000">'Step must be -ve'</span><span style="color: #007700">);<br /> }<br /><br /> for (</span><span style="color: #0000BB">$i </span><span style="color: #007700">= </span><span style="color: #0000BB">$start</span><span style="color: #007700">; </span><span style="color: #0000BB">$i </span><span style="color: #007700">>= </span><span style="color: #0000BB">$limit</span><span style="color: #007700">; </span><span style="color: #0000BB">$i </span><span style="color: #007700">+= </span><span style="color: #0000BB">$step</span><span style="color: #007700">) {<br /> </span><span style="color: #0000BB">yield $i</span><span style="color: #007700">;<br /> }<br /> }<br />}<br /><br /></span><span style="color: #FF8000">/*<br /> * Note that both range() and xrange() result in the same<br /> * output below.<br /> */<br /><br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">'Single digit odd numbers from range(): '</span><span style="color: #007700">;<br />foreach (</span><span style="color: #0000BB">range</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">9</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">) as </span><span style="color: #0000BB">$number</span><span style="color: #007700">) {<br /> echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$number</span><span style="color: #DD0000"> "</span><span style="color: #007700">;<br />}<br />echo </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br />echo </span><span style="color: #DD0000">'Single digit odd numbers from xrange(): '</span><span style="color: #007700">;<br />foreach (</span><span style="color: #0000BB">xrange</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">, </span><span style="color: #0000BB">9</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">) as </span><span style="color: #0000BB">$number</span><span style="color: #007700">) {<br /> echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$number</span><span style="color: #DD0000"> "</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?></span> </span> </code></div> </div> <div class="example-contents"><p>The above example will output:</p></div> <div class="example-contents screen"> <div class="cdata"><pre> Single digit odd numbers from range(): 1 3 5 7 9 Single digit odd numbers from xrange(): 1 3 5 7 9 </pre></div> </div> </div> </div><hr /><div class="manualnavbar" style="text-align: center;"> <div class="prev" style="text-align: left; float: left;"><a href="language.generators.html">Generators</a></div> <div class="next" style="text-align: right; float: right;"><a href="language.generators.syntax.html">Generator syntax</a></div> <div class="up"><a href="language.generators.html">Generators</a></div> <div class="home"><a href="index.html">PHP Manual</a></div> </div></body></html>