<?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 => 'fr',
  ),
  'this' => 
  array (
    0 => 'language.generators.syntax.php',
    1 => 'Syntaxe d\'un G&eacute;n&eacute;rateur',
    2 => 'Syntaxe d\'un G&eacute;n&eacute;rateur',
  ),
  'up' => 
  array (
    0 => 'language.generators.php',
    1 => 'Les g&eacute;n&eacute;rateurs',
  ),
  'prev' => 
  array (
    0 => 'language.generators.overview.php',
    1 => 'R&eacute;sum&eacute; sur les g&eacute;n&eacute;rateurs',
  ),
  'next' => 
  array (
    0 => 'language.generators.comparison.php',
    1 => 'Comparaison des g&eacute;n&eacute;rateurs avec les objets Iterator',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'fr',
    '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">Syntaxe d&#039;un Générateur</h2>
  
  <p class="para">
   Une fonction générateur ressemble à une fonction normale, sauf qu&#039;au lieu de
   retourner une valeur, un générateur <a href="language.generators.syntax.php#control-structures.yield" class="link"><code class="literal">yield</code></a> retourne autant de valeurs que nécessaire.
   Toute fonction contenant <a href="language.generators.syntax.php#control-structures.yield" class="link"><code class="literal">yield</code></a> est une fonction générateur.
  </p>

  <p class="para">
   Lorsqu&#039;une fonction générateur est appelée, elle retourne un objet
   que l&#039;on peut parcourir. Lors du parcours de cet objet (par exemple, via une
   boucle <a href="control-structures.foreach.php" class="link"><code class="literal">foreach</code></a>), PHP appellera les méthodes d&#039;itération de l&#039;objet chaque
   fois qu&#039;il a besoin d&#039;une valeur, puis sauvegarde le statut du générateur
   lorsqu&#039;il génère une valeur, pour qu&#039;il puisse être repris lorsque
   la prochaine valeur sera requise.
  </p>
  
  <p class="para">
   Lorsqu&#039;il n&#039;y a plus de valeur à fournir, la fonction générateur peut simplement
   retourner, et le code appelant continuera comme si un tableau n&#039;avait plus de valeur.
  </p>
  
  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    Un générateur peut retourner des valeurs,
    qui peuvent être récupérées en utilisant <span class="methodname"><a href="generator.getreturn.php" class="methodname">Generator::getReturn()</a></span>.
   </p>
  </p></blockquote>
  
  <div class="sect2" id="control-structures.yield">
   <h3 class="title">Le mot-clé <strong class="command">yield</strong></h3>
   
   <p class="para">
    Le mot clé <strong class="command">yield</strong> est le cœur d&#039;une fonction générateur.
    Dans sa forme la plus simple, une instruction yield ressemble à une instruction
    return, excepté qu&#039;au lieu de stopper l&#039;exécution de la fonction
    et de retourner, yield fournit une valeur au code parcourant le générateur,
    et met en pause l&#039;exécution de la fonction générateur.
   </p>
   
   <div class="example" id="example-1">
    <p><strong>Exemple #1 Un exemple simple de production de valeurs</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">gen_one_to_three</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">// $i est préservé entre chaque production de valeur.<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">gen_one_to_three</span><span style="color: #007700">();<br />foreach (</span><span style="color: #0000BB">$generator </span><span style="color: #007700">as </span><span style="color: #0000BB">$value</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$value</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>L&#039;exemple ci-dessus va afficher :</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">Note</strong>: 
    <p class="para">
     En interne, des clés séquentielles entières seront associées
     avec les valeurs produites, de la même manière que pour un
     tableau non-associatif.
    </p>
   </p></blockquote>
   
   <div class="sect3" id="control-structures.yield.associative">
    <h4 class="title">Fourniture de valeurs avec des clés</h4>
    
    <p class="para">
     PHP supporte également les tableaux associatifs, et les générateurs
     ne sont pas différents. En plus de fournir des valeurs simples, comme nous
     l&#039;avons vu plus haut, il est aussi possible, en même temps, de fournir une clé.
    </p>
    
    <p class="para">
     La syntaxe permettant de produire une paire clé/valeur est similaire à celle utilisée
     pour définir un tableau associatif ; comme ceci :
    </p>
    
    <div class="example" id="example-2">
     <p><strong>Exemple #2 Production d&#039;une paire clé/valeur</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 /> * L'entrée est constituée de champs séparés par un point-virgule,<br /> * et le premier champ est un ID à utiliser comme clé.<br /> */<br /><br /></span><span style="color: #0000BB">$input </span><span style="color: #007700">= &lt;&lt;&lt;'EOF'<br /></span><span style="color: #DD0000">1;PHP;Likes dollar signs<br />2;Python;Likes whitespace<br />3;Ruby;Likes blocks<br /></span><span style="color: #007700">EOF;<br /><br />function </span><span style="color: #0000BB">input_parser</span><span style="color: #007700">(</span><span style="color: #0000BB">$input</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">$input</span><span style="color: #007700">) as </span><span style="color: #0000BB">$line</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$fields </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">$line</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">$fields</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">$fields</span><span style="color: #007700">;<br />    }<br />}<br /><br />foreach (</span><span style="color: #0000BB">input_parser</span><span style="color: #007700">(</span><span style="color: #0000BB">$input</span><span style="color: #007700">) as </span><span style="color: #0000BB">$id </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">$fields</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">$fields</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">$fields</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>L&#039;exemple ci-dessus va afficher :</p></div>
     <div class="example-contents screen">
<div class="cdata"><pre>
1:
    PHP
    Likes dollar signs
2:
    Python
    Likes whitespace
3:
    Ruby
    Likes blocks
</pre></div>
     </div>
    </div>
   </div>
   
   <div class="sect3" id="control-structures.yield.null">
    <h4 class="title">Production de valeurs nulles</h4>
    
    <p class="para">
     Yield peut être appelé sans argument pour fournir une valeur nulle
     avec une clé automatique.
    </p>
    
    <div class="example" id="example-3">
     <p><strong>Exemple #3 Production de valeurs nulles</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">gen_three_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">gen_three_nulls</span><span style="color: #007700">()));<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

     <div class="example-contents"><p>L&#039;exemple ci-dessus va afficher :</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">Production de valeurs par référence</h4>
    
    <p class="para">
     Les fonctions générateur peuvent produire des valeurs par référence.
     Ceci se fait de la même façon que le
     <a href="functions.returning-values.php" class="link">retour par référence
      depuis des fonctions</a> : en ajoutant un ET commercial (&amp;) au nom
     de la fonction.
    </p>
    
    <div class="example" id="example-4">
     <p><strong>Exemple #4 Production de valeurs par référence</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">gen_reference</span><span style="color: #007700">() {<br />    </span><span style="color: #0000BB">$value </span><span style="color: #007700">= </span><span style="color: #0000BB">3</span><span style="color: #007700">;<br /><br />    while (</span><span style="color: #0000BB">$value </span><span style="color: #007700">&gt; </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br />        yield </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #FF8000">/*<br /> * Il est à noter qu'il est possible de changer $number dans la boucle,<br /> * et, du fait que le générateur fournit des références, $value<br /> * dans gen_reference() change aussi.<br /> */<br /></span><span style="color: #007700">foreach (</span><span style="color: #0000BB">gen_reference</span><span style="color: #007700">() as &amp;</span><span style="color: #0000BB">$number</span><span style="color: #007700">) {<br />    echo (--</span><span style="color: #0000BB">$number</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>L&#039;exemple ci-dessus va afficher :</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">Délégation du générateur via <strong class="command">yield from</strong></h4>

    <p class="para">
     La délégation du générateur permet d&#039;obtenir les valeurs d&#039;un
     autre générateur, d&#039;un objet <span class="classname"><a href="class.traversable.php" class="classname">Traversable</a></span>, ou
     d&#039;un <span class="type"><a href="language.types.array.php" class="type array">array</a></span> en utilisant le mot clé <strong class="command">yield from</strong>.
     Le générateur externe va ainsi obtenir toutes les valeurs du générateur
     interne, de l&#039;objet, ou du tableau tant qu&#039;il n&#039;est pas invalide, après
     quoi, l&#039;exécution va continuer dans le générateur externe.
    </p>

    <p class="para">
     Si un générateur est utilisé avec l&#039;expression <strong class="command">yield from</strong>,
     l&#039;expression <strong class="command">yield from</strong> va aussi retourner toute valeur
     retournée par le générateur interne.
    </p>
    
    <div class="caution"><strong class="caution">Attention</strong>
     <h1 class="title">Stocker dans un tableau (e.g. avec <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> ne réinitialise pas les
       clés. Il préserve les clés retournées par l&#039;objet
       <span class="classname"><a href="class.traversable.php" class="classname">Traversable</a></span>, ou <span class="type"><a href="language.types.array.php" class="type array">array</a></span>. 
       Donc, certaines valeurs peuvent partager une clé commune avec d&#039;autres <strong class="command">yield</strong> ou
       <strong class="command">yield from</strong>, qui, lors de l&#039;insertion
       dans un tableau, écrasera les anciennes valeurs avec cette clé.
      </p>

      <p class="para">
       Un cas fréquent où cela est important est <span class="function"><a href="function.iterator-to-array.php" class="function">iterator_to_array()</a></span>
       renvoyant un tableau avec clé par défaut, conduisant à
       des résultats éventuellement inattendus.
       <span class="function"><a href="function.iterator-to-array.php" class="function">iterator_to_array()</a></span> a un second paramètre
       <code class="parameter">preserve_keys</code> qui peut être défini sur <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>
       pour collecter toutes les valeurs en ignorant les clés
       renvoyées par le <span class="classname"><a href="class.generator.php" class="classname">Generator</a></span>.
      </p>
     
      <div class="example" id="example-5">
       <p><strong>Exemple #5 <strong class="command">yield from</strong> avec <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">// clé 0<br />    </span><span style="color: #007700">yield </span><span style="color: #0000BB">2</span><span style="color: #007700">; </span><span style="color: #FF8000">// clé 1<br />    </span><span style="color: #007700">yield </span><span style="color: #0000BB">3</span><span style="color: #007700">; </span><span style="color: #FF8000">// clé 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">// clé 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">// clés 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">// clé 1<br /></span><span style="color: #007700">}<br /></span><span style="color: #FF8000">// met à false le second paramètre pour avoir un tableau [0, 1, 2, 3, 4]<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>L&#039;exemple ci-dessus va afficher :</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>Exemple #6 Utilisation basique de <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">count_to_ten</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">seven_eight</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">seven_eight</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">eight</span><span style="color: #007700">();<br />}<br /><br />function </span><span style="color: #0000BB">eight</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">count_to_ten</span><span style="color: #007700">() as </span><span style="color: #0000BB">$num</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$num</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>L&#039;exemple ci-dessus va afficher :</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>Exemple #7 <strong class="command">yield from</strong> et les valeurs retournées</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">count_to_ten</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">seven_eight</span><span style="color: #007700">();<br />    return yield from </span><span style="color: #0000BB">nine_ten</span><span style="color: #007700">();<br />}<br /><br />function </span><span style="color: #0000BB">seven_eight</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">eight</span><span style="color: #007700">();<br />}<br /><br />function </span><span style="color: #0000BB">eight</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">nine_ten</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">count_to_ten</span><span style="color: #007700">();<br />foreach (</span><span style="color: #0000BB">$gen </span><span style="color: #007700">as </span><span style="color: #0000BB">$num</span><span style="color: #007700">) {<br />    echo </span><span style="color: #DD0000">"</span><span style="color: #0000BB">$num</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>L&#039;exemple ci-dessus va afficher :</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); ?>