<?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.syntax.php',
    1 => 'Generator-Syntax',
    2 => 'Generator-Syntax',
  ),
  'up' => 
  array (
    0 => 'language.generators.php',
    1 => 'Generatoren',
  ),
  'prev' => 
  array (
    0 => 'language.generators.overview.php',
    1 => 'Generatoren-&Uuml;bersicht',
  ),
  'next' => 
  array (
    0 => 'language.generators.comparison.php',
    1 => 'Vergleich von Generatoren mit Iterator-Objekten',
  ),
  '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.syntax" class="sect1">
  <h2 class="title">Generator-Syntax</h2>

  <p class="para">
   Eine Generatorfunktion sieht genau so aus wie eine normale Funktion mit
   der Ausnahme, dass ein Generator statt eines Wertes so viele Werte wie
   nötig zurückgibt (Stichwort: <a href="language.generators.syntax.php#control-structures.yield" class="link"><code class="literal">yield</code></a>).
   Jede Funktion, die <a href="language.generators.syntax.php#control-structures.yield" class="link"><code class="literal">yield</code></a> enthält, ist eine Generatorfunktion.
  </p>

  <p class="para">
   Wenn eine Generatorfunktion aufgerufen wird, wird ein Objekt zurückgegeben,
   über das iteriert werden kann. Wenn Sie über dieses Objekt iterieren (zum
   Beispiel, per <a href="control-structures.foreach.php" class="link"><code class="literal">foreach</code></a>-Schleife), wird PHP die Iteratorfunktionen des
   Objekts jedes Mal aufrufen, wenn ein Wert benötigt wird. Dann wird der
   Status des Generators gesichert, so dass fortgefahren werden kann, wenn der
   nächste Wert benötigt wird.
  </p>

  <p class="para">
   Sobald keine weiteren Werte zurückgegeben werden können, kann der
   Generator einfach zurückgeben, und der rufende Code wird
   fortgesetzt, als gäbe es keine weiteren Werte in einem Array.
  </p>

  <blockquote class="note"><p><strong class="note">Hinweis</strong>: 
   <p class="para">
    Ein Generator kann Werte zurückgeben, die unter Verwendung von
    <span class="methodname"><a href="generator.getreturn.php" class="methodname">Generator::getReturn()</a></span> ermittelt werden können.
   </p>
  </p></blockquote>

  <div class="sect2" id="control-structures.yield">
   <h3 class="title"><strong class="command">yield</strong>-Schlüsselwort</h3>

   <p class="para">
    Das Herz einer Generatorfunktion ist das
    <strong class="command">yield</strong>-Schlüsselwort. In seiner einfachsten Form sieht
    das yield-Schlüsselwort wie eine return-Anweisung aus, ausser dass die
    Ausführung mit der Rückgabe nicht beendet wird, sondern yield stattdessen
    bei der Schleife über den Generator einen Wert für den Code bereitstellt
    und die Ausführung der Generatorfunktion anhält.
   </p>

   <div class="example" id="example-1">
    <p><strong>Beispiel #1 Ein einfaches Beispiel zum liefern (yielding) von Werten</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">generiere_eins_bis_drei</span><span style="color: #007700">() {<br />    for (</span><span style="color: #0000BB">$i </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">; </span><span style="color: #0000BB">$i </span><span style="color: #007700">&lt;= </span><span style="color: #0000BB">3</span><span style="color: #007700">; </span><span style="color: #0000BB">$i</span><span style="color: #007700">++) {<br />        </span><span style="color: #FF8000">// Hinweis: $i bleibt zwischen den yields erhalten.<br />        </span><span style="color: #007700">yield </span><span style="color: #0000BB">$i</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$generator </span><span style="color: #007700">= </span><span style="color: #0000BB">generiere_eins_bis_drei</span><span style="color: #007700">();<br />foreach (</span><span style="color: #0000BB">$generator </span><span style="color: #007700">as </span><span style="color: #0000BB">$wert</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$wert</span><span style="color: #DD0000">\n"</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>
1
2
3
</pre></div>
    </div>
   </div>

   <blockquote class="note"><p><strong class="note">Hinweis</strong>: 
    <p class="para">
     Intern werden sequentielle Integer-Schlüssel mit den abgelieferten Werten
     verknüpft, so wie mit einem nicht-assoziativen Array.
    </p>
   </p></blockquote>

   <div class="sect3" id="control-structures.yield.associative">
    <h4 class="title">Produzieren von Werten mit Schlüsseln</h4>

    <p class="para">
     PHP unterstützt ebenfalls assoziative Arrays, und Generatoren
     unterscheiden sich nicht davon. Als Ergänzung zum Produzieren einfacher
     Werte, wie oben gezeigt, können Sie zur gleichen Zeit auch einen
     Schlüssel liefern.
    </p>

    <p class="para">
     Die Syntax für das Produzieren eines Schlüssel/Wert-Paares ist sehr
     ähnlich wie die Definition von assoziativen Arrays, wie unten gezeigt.
    </p>

    <div class="example" id="example-2">
     <p><strong>Beispiel #2 Produzieren eines Schlüssel/Wert-Paares</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: #FF8000">/*<br /> * Die Eingabe sind Semikolon getrennte Felder, wobei das erste Feld<br /> * eine ID ist, die als Schlüssel genutzt wird.<br /> */<br /><br /></span><span style="color: #0000BB">$eingabe </span><span style="color: #007700">= &lt;&lt;&lt;'EOF'<br /></span><span style="color: #DD0000">1;PHP;mag Dollarzeichen<br />2;Python;mag Leerzeichen<br />3;Ruby;mag Blöcke<br /></span><span style="color: #007700">EOF;<br /><br />function </span><span style="color: #0000BB">eingabe_parser</span><span style="color: #007700">(</span><span style="color: #0000BB">$eingabe</span><span style="color: #007700">) {<br />    foreach (</span><span style="color: #0000BB">explode</span><span style="color: #007700">(</span><span style="color: #DD0000">"\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$eingabe</span><span style="color: #007700">) as </span><span style="color: #0000BB">$zeile</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$felder </span><span style="color: #007700">= </span><span style="color: #0000BB">explode</span><span style="color: #007700">(</span><span style="color: #DD0000">';'</span><span style="color: #007700">, </span><span style="color: #0000BB">$zeile</span><span style="color: #007700">);<br />        </span><span style="color: #0000BB">$id </span><span style="color: #007700">= </span><span style="color: #0000BB">array_shift</span><span style="color: #007700">(</span><span style="color: #0000BB">$felder</span><span style="color: #007700">);<br /><br />        yield </span><span style="color: #0000BB">$id </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$felder</span><span style="color: #007700">;<br />    }<br />}<br /><br />foreach (</span><span style="color: #0000BB">eingabe_parser</span><span style="color: #007700">(</span><span style="color: #0000BB">$eingabe</span><span style="color: #007700">) as </span><span style="color: #0000BB">$id </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$felder</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$id</span><span style="color: #DD0000">:\n"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"    </span><span style="color: #0000BB">$felder</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">]</span><span style="color: #DD0000">\n"</span><span style="color: #007700">;<br />    echo </span><span style="color: #DD0000">"    </span><span style="color: #0000BB">$felder</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">]</span><span style="color: #DD0000">\n"</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>
1:
    PHP
    mag Dollarzeichen
2:
    Python
    mag Leerzeichen
3:
    Ruby
    mag Blöcke
</pre></div>
     </div>
    </div>
   </div>

   <div class="sect3" id="control-structures.yield.null">
    <h4 class="title">Produzieren von null-Werten</h4>

    <p class="para">
     Yield kann ohne Argument aufgerufen werden, um einen <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong>-Wert mit
     einem automatischen Schlüssel zurückzugeben.
    </p>

    <div class="example" id="example-3">
     <p><strong>Beispiel #3 Produzieren von <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong>s</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">generiere_drei_nulls</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">3</span><span style="color: #007700">) as </span><span style="color: #0000BB">$i</span><span style="color: #007700">) {<br />        yield;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">iterator_to_array</span><span style="color: #007700">(</span><span style="color: #0000BB">generiere_drei_nulls</span><span style="color: #007700">()));<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>
array(3) {
  [0]=&gt;
  NULL
  [1]=&gt;
  NULL
  [2]=&gt;
  NULL
}
</pre></div>
     </div>
    </div>
   </div>

   <div class="sect3" id="control-structures.yield.references">
    <h4 class="title">Produzieren als Referenz</h4>

    <p class="para">
     Generatorfunktionen sind genauso in der Lage Werte als Referenz
     zurückzugeben, wie als Wert. Dies kann in gleicher Weise erfolgen, wie
     beim
     <a href="functions.returning-values.php" class="link">Zurückgeben von Referenzen aus Funktionen</a>:
     dies geschieht, indem dem Funktionsnamen ein Kaufmanns-Und vorangestellt
     wird.
    </p>

    <div class="example" id="example-4">
     <p><strong>Beispiel #4 Produzieren von Werten als Referenz</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 &amp;</span><span style="color: #0000BB">generiere_referenz</span><span style="color: #007700">() {<br />    </span><span style="color: #0000BB">$wert </span><span style="color: #007700">= </span><span style="color: #0000BB">3</span><span style="color: #007700">;<br /><br />    while (</span><span style="color: #0000BB">$wert </span><span style="color: #007700">&gt; </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br />        yield </span><span style="color: #0000BB">$wert</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #FF8000">/*<br /> * Hinweis: wir können $nummer innerhalb der Schleife ändern,<br /> * und weil der Generator Referenzen zurückgibt, wird $wert<br /> * innerhalb von generiere_referenz() verändert.<br /> */<br /></span><span style="color: #007700">foreach (</span><span style="color: #0000BB">generiere_referenz</span><span style="color: #007700">() as &amp;</span><span style="color: #0000BB">$nummer</span><span style="color: #007700">) {<br />    echo (--</span><span style="color: #0000BB">$nummer</span><span style="color: #007700">).</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>
2... 1... 0...
</pre></div>
     </div>
    </div>
   </div>

   <div class="sect3" id="control-structures.yield.from">
    <h4 class="title">Generatordelegation per <strong class="command">yield from</strong></h4>

    <p class="para">
     Die Generatordelegation ermöglicht, mittels
     <strong class="command">yield from</strong>-Ausdruck Werte von einem anderen Generator,
     <span class="classname"><a href="class.traversable.php" class="classname">Traversable</a></span>-Objekt oder <span class="type"><a href="language.types.array.php" class="type Array">Array</a></span>
     liefern zu lassen. Der äußere Generator liefert dann alle Werte vom
     inneren Generator, Objekt oder Array, bis dies nicht mehr gültig
     ist und die Ausführung im äußeren Generator fortfährt.
    </p>

    <p class="para">
     Falls ein Generator mit <strong class="command">yield from</strong> verwendet wird,
     gibt der <strong class="command">yield from</strong>-Ausdruck auch alle Werte zurück,
     die vom inneren Generator zurückgegeben werden.
    </p>

    <div class="caution"><strong class="caution">Achtung</strong>
     <h1 class="title">Speichern in ein Array (z. B. mit <span class="function"><a href="function.iterator-to-array.php" class="function">iterator_to_array()</a></span>)</h1>

      <p class="para">
       <strong class="command">yield from</strong> setzt nicht die Schlüssel zurück. Es erhält
       die Schlüssel, die vom <span class="classname"><a href="class.traversable.php" class="classname">Traversable</a></span>-Objekt oder
       <span class="type"><a href="language.types.array.php" class="type Array">Array</a></span> zurückgegeben wurden. Daher können einige Werte den
       selben Schlüssel mit einem anderen <strong class="command">yield</strong> oder
       <strong class="command">yield from</strong> gemein haben, der, bei der Einfügung in ein
       Array, vorherige Werte mit diesem Schlüssel überschreibt.
      </p>

      <p class="para">
       Ein üblicher Fall, für den dies relevant ist, ist
       <span class="function"><a href="function.iterator-to-array.php" class="function">iterator_to_array()</a></span>, das standardmäßig ein indexiertes
       Array zurück gibt, was zu möglicherweise unerwarteten Ergebnissen führen
       kann. <span class="function"><a href="function.iterator-to-array.php" class="function">iterator_to_array()</a></span> hat einen zweiten Parameter
       <code class="parameter">preserve_keys</code>, der auf <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong> gesetzt werden
       kann, um alle Werte zu sammeln, während die Schlüssel, die vom
       <span class="classname"><a href="class.generator.php" class="classname">Generator</a></span> geliefert werden, ignoriert werden.
      </p>

      <div class="example" id="example-5">
       <p><strong>Beispiel #5 <strong class="command">yield from</strong> mit <span class="function"><a href="function.iterator-to-array.php" class="function">iterator_to_array()</a></span></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">inner</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">1</span><span style="color: #007700">; </span><span style="color: #FF8000">// Schlüssel 0<br />    </span><span style="color: #007700">yield </span><span style="color: #0000BB">2</span><span style="color: #007700">; </span><span style="color: #FF8000">// Schlüssel 1<br />    </span><span style="color: #007700">yield </span><span style="color: #0000BB">3</span><span style="color: #007700">; </span><span style="color: #FF8000">// Schlüssel 2<br /></span><span style="color: #007700">}<br />function </span><span style="color: #0000BB">gen</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">0</span><span style="color: #007700">; </span><span style="color: #FF8000">// Schlüssel 0<br />    </span><span style="color: #007700">yield from </span><span style="color: #0000BB">inner</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Schlüssel 0-2<br />    </span><span style="color: #007700">yield </span><span style="color: #0000BB">4</span><span style="color: #007700">; </span><span style="color: #FF8000">// Schlüssel 1<br /></span><span style="color: #007700">}<br /></span><span style="color: #FF8000">// Übergib false als zweiten Parameter, um das Array [0, 1, 2, 3, 4] zu erhalten<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">iterator_to_array</span><span style="color: #007700">(</span><span style="color: #0000BB">gen</span><span style="color: #007700">()));<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>
array(3) {
  [0]=&gt;
  int(1)
  [1]=&gt;
  int(4)
  [2]=&gt;
  int(3)
}
</pre></div>
       </div>
      </div>
    </div>

    <div class="example" id="example-6">
     <p><strong>Beispiel #6 Grundlegende Verwendung von <strong class="command">yield from</strong></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">zaehle_bis_zehn</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />    yield </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br />    yield from [</span><span style="color: #0000BB">3</span><span style="color: #007700">, </span><span style="color: #0000BB">4</span><span style="color: #007700">];<br />    yield from new </span><span style="color: #0000BB">ArrayIterator</span><span style="color: #007700">([</span><span style="color: #0000BB">5</span><span style="color: #007700">, </span><span style="color: #0000BB">6</span><span style="color: #007700">]);<br />    yield from </span><span style="color: #0000BB">sieben_acht</span><span style="color: #007700">();<br />    yield </span><span style="color: #0000BB">9</span><span style="color: #007700">;<br />    yield </span><span style="color: #0000BB">10</span><span style="color: #007700">;<br />}<br /><br />function </span><span style="color: #0000BB">sieben_acht</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">7</span><span style="color: #007700">;<br />    yield from </span><span style="color: #0000BB">acht</span><span style="color: #007700">();<br />}<br /><br />function </span><span style="color: #0000BB">acht</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">8</span><span style="color: #007700">;<br />}<br /><br />foreach (</span><span style="color: #0000BB">zaehle_bis_zehn</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>
1 2 3 4 5 6 7 8 9 10
</pre></div>
     </div>
    </div>

    <div class="example" id="example-7">
     <p><strong>Beispiel #7 <strong class="command">yield from</strong> und Rückgabewerte</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">zaehle_bis_zehn</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />    yield </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br />    yield from [</span><span style="color: #0000BB">3</span><span style="color: #007700">, </span><span style="color: #0000BB">4</span><span style="color: #007700">];<br />    yield from new </span><span style="color: #0000BB">ArrayIterator</span><span style="color: #007700">([</span><span style="color: #0000BB">5</span><span style="color: #007700">, </span><span style="color: #0000BB">6</span><span style="color: #007700">]);<br />    yield from </span><span style="color: #0000BB">sieben_acht</span><span style="color: #007700">();<br />    return yield from </span><span style="color: #0000BB">neun_zehn</span><span style="color: #007700">();<br />}<br /><br />function </span><span style="color: #0000BB">sieben_acht</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">7</span><span style="color: #007700">;<br />    yield from </span><span style="color: #0000BB">acht</span><span style="color: #007700">();<br />}<br /><br />function </span><span style="color: #0000BB">acht</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">8</span><span style="color: #007700">;<br />}<br /><br />function </span><span style="color: #0000BB">neun_zehn</span><span style="color: #007700">() {<br />    yield </span><span style="color: #0000BB">9</span><span style="color: #007700">;<br />    return </span><span style="color: #0000BB">10</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$gen </span><span style="color: #007700">= </span><span style="color: #0000BB">zaehle_bis_zehn</span><span style="color: #007700">();<br />foreach (</span><span style="color: #0000BB">$gen </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: #0000BB">$gen</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getReturn</span><span style="color: #007700">();<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>
1 2 3 4 5 6 7 8 9 10
</pre></div>
     </div>
    </div>
   </div>
  </div>
 </div><?php manual_footer($setup); ?>