<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.generators.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'de',
  ),
  'this' => 
  array (
    0 => 'language.generators.overview.php',
    1 => 'Generatoren-&Uuml;bersicht',
    2 => 'Generatoren-&Uuml;bersicht',
  ),
  'up' => 
  array (
    0 => 'language.generators.php',
    1 => 'Generatoren',
  ),
  'prev' => 
  array (
    0 => 'language.generators.php',
    1 => 'Generatoren',
  ),
  'next' => 
  array (
    0 => 'language.generators.syntax.php',
    1 => 'Generator-Syntax',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'de',
    'path' => 'language/generators.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.generators.overview" class="sect1">
  <h2 class="title">Generatoren-Übersicht</h2>
  <p class="verinfo">(PHP 5 &gt;= 5.5.0, PHP 7, PHP 8)</p>

  <p class="para">
   Generatoren bieten eine einfache Möglichkeit, um einfache
   <a href="language.oop5.iterations.php" class="link">Iteratoren</a> zu erstellen,
   ohne den Overhead oder die Komplexität der Erstellung einer Klasse zu
   haben, die das <span class="classname"><a href="class.iterator.php" class="classname">Iterator</a></span>-Interface implementiert.
  </p>

  <p class="para">
   Mit einem Generator können auf bequeme Weise Daten für <a href="control-structures.foreach.php" class="link"><code class="literal">foreach</code></a> -Schleifen
   bereitgestellt werden, ohne ein Array im Speicher zu erzeugen, was dazu
   führen kann, dass das Programm ein Speicherlimit überschreitet oder
   beträchtliche Prozessorzeit benötigt. Alternativ kann eine Generatorfunktion
   verwendet werden, die einer normalen
   <a href="functions.user-defined.php" class="link">Funktion</a> entspricht, bei der
   aber keine einmalige
   <a href="functions.returning-values.php" class="link">Rückgabe</a> erfolgt, sondern
   der Generator so oft wie nötig einen Wert abgibt (Stichwort: <a href="language.generators.syntax.php#control-structures.yield" class="link"><code class="literal">yield</code></a>), um
   die Werte zu liefern, über die iteriert werden soll.
   Wie bei Iteratoren ist ein wahlfreier Datenzugriff nicht möglich.
  </p>

  <p class="para">
   Ein einfaches Beispiel dazu ist, die <span class="function"><a href="function.range.php" class="function">range()</a></span>-Funktion
   durch einen Generator neu zu implementieren. Die
   Standard-<span class="function"><a href="function.range.php" class="function">range()</a></span>-Funktion generiert und liefert Arrays,
   welche jeden Wert enthalten, was große Arrays zur Folge haben kann: zum
   Beispiel hat der Aufruf <strong class="command">range(0, 1000000)</strong> zur Folge,
   dass weit über 100 MB an Speicher benötigt werden.
  </p>

  <p class="para">
   Als Alternative können wir einen <code class="literal">xrange()</code>-Generator
   implementieren, welcher immer nur genug Speicher benötigt, um ein
   <span class="classname"><a href="class.iterator.php" class="classname">Iterator</a></span>-Objekt zu erzeugen und intern den aktuellen
   Zustand des Generators zu verfolgen, was sich als weniger als 1 Kilobyte
   herausstellt.
  </p>

  <div class="example" id="example-1">
   <p><strong>Beispiel #1 Implementierung von <span class="function"><a href="function.range.php" class="function">range()</a></span> als Generator</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?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">&lt;= </span><span style="color: #0000BB">$limit</span><span style="color: #007700">) {<br />        if (</span><span style="color: #0000BB">$step </span><span style="color: #007700">&lt;= </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">'Schrittweite muss positiv sein'</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">&lt;= </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 />            yield </span><span style="color: #0000BB">$i</span><span style="color: #007700">;<br />        }<br />    } else {<br />        if (</span><span style="color: #0000BB">$step </span><span style="color: #007700">&gt;= </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">'Schrittweite muss negativ sein'</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">&gt;= </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 />            yield </span><span style="color: #0000BB">$i</span><span style="color: #007700">;<br />        }<br />    }<br />}<br /><br /></span><span style="color: #FF8000">/*<br /> * Hinweis: sowohl range() als auch xrange()<br /> * erzeugen die gleiche Ausgabe.<br /> */<br /><br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">'Einstellige ungerade Zahlen von 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">$zahl</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$zahl</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">'Einstellige ungerade Zahlen von 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">$zahl</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$zahl</span><span style="color: #DD0000"> "</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>Das oben gezeigte Beispiel erzeugt folgende Ausgabe:</p></div>
   <div class="example-contents screen">
<div class="cdata"><pre>
Einstellige ungerade Zahlen von range():  1 3 5 7 9
Einstellige ungerade Zahlen von xrange(): 1 3 5 7 9
</pre></div>
   </div>
  </div>

  <div class="sect2" id="language.generators.object">
   <h3 class="title"><span class="classname"><a href="class.generator.php" class="classname">Generator</a></span>-Objekte</h3>
   <p class="para">
    Beim Aufruf einer Generatorfunktion wird ein neues Objekt der internen
    <span class="classname"><a href="class.generator.php" class="classname">Generator</a></span>-Klasse zurückgegeben. Dieses Objekt
    implementiert das <span class="classname"><a href="class.iterator.php" class="classname">Iterator</a></span>-Interface in gleicher
    Weise wie es ein forward-only Iterator-Objekt machen würde und stellt
    Methoden zur Verfügung, die aufgerufen werden können, um den Zustand des
    Generators zu manipulieren, einschließlich des Sendens von Werten an,
    und der Rückgabe von Werten von ihm.
   </p>
  </div>
 </div><?php manual_footer($setup); ?>