<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.oop5.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'fr',
  ),
  'this' => 
  array (
    0 => 'language.oop5.overloading.php',
    1 => 'Surcharge magique',
    2 => 'Surcharge magique',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Les classes et les objets',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.anonymous.php',
    1 => 'Classes anonymes',
  ),
  'next' => 
  array (
    0 => 'language.oop5.iterations.php',
    1 => 'Parcours d\'objets',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'fr',
    'path' => 'language/oop5/overloading.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.overloading" class="sect1">
  <h2 class="title">Surcharge magique</h2>

  <p class="para">
   La surcharge magique en PHP permet de &quot;créer&quot; dynamiquement des
   propriétés et des méthodes. Ces entités dynamiques sont
   traitées via des méthodes magiques établies que l&#039;on peut positionner
   dans une classe pour divers types d&#039;actions.
  </p>

  <p class="para">
   Les méthodes magiques de surcharge sont appelées lors de l&#039;interaction
   avec des propriétés ou des méthodes qui n&#039;ont pas été déclarées
   ou ne sont pas <a href="language.oop5.visibility.php" class="link">visibles</a>
   dans le contexte courant. Le reste de cette section utilise
   les termes de <q class="quote">propriétés inaccessibles</q> et de
   <q class="quote">méthodes inaccessibles</q> pour se référer à cette
   combinaison de déclaration et de visibilité.
  </p>

  <p class="para">
   Toutes les méthodes magiques de surcharge doivent être définies comme
   <code class="literal">public</code>.
  </p>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    Aucun des arguments de ces méthodes magiques ne peut être
    <a href="functions.arguments.php#functions.arguments.by-reference" class="link">passé par
    référence</a>.
   </p>
  </p></blockquote>

  <blockquote class="note"><p><strong class="note">Note</strong>: 
   <p class="para">
    L&#039;interprétation PHP de la <q class="quote">surcharge</q> est
    différente de celle de la plupart des langages orientés objet.
    La surcharge, habituellement, fournit la possibilité d&#039;avoir
    plusieurs méthodes portant le même nom mais avec une quantité
    et des types différents d&#039;arguments.
   </p>
  </p></blockquote>

  <div class="sect2" id="language.oop5.overloading.members">
   <h3 class="title">Surcharge de propriétés</h3>

   <div class="methodsynopsis dc-description" id="object.set">
    <span class="modifier">public</span> <span class="methodname"><strong>__set</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.string.php" class="type string">string</a></span> <code class="parameter">$name</code></span>, <span class="methodparam"><span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span> <code class="parameter">$value</code></span>): <span class="type"><a href="language.types.void.php" class="type void">void</a></span></div>

   <div class="methodsynopsis dc-description" id="object.get"><span class="modifier">public</span> <span class="methodname"><strong>__get</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.string.php" class="type string">string</a></span> <code class="parameter">$name</code></span>): <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span></div>

   <div class="methodsynopsis dc-description" id="object.isset"><span class="modifier">public</span> <span class="methodname"><strong>__isset</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.string.php" class="type string">string</a></span> <code class="parameter">$name</code></span>): <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span></div>

   <div class="methodsynopsis dc-description" id="object.unset"><span class="modifier">public</span> <span class="methodname"><strong>__unset</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.string.php" class="type string">string</a></span> <code class="parameter">$name</code></span>): <span class="type"><a href="language.types.void.php" class="type void">void</a></span></div>


   <p class="para">
    <a href="language.oop5.overloading.php#object.set" class="link">__set()</a> est sollicitée lors de l&#039;écriture de données
    vers des propriétés inaccessibles (protégées ou privées) ou non existantes.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> est appelée pour lire des données depuis
    des propriétés inaccessibles (protégées ou privées) ou non existantes.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.isset" class="link">__isset()</a> est sollicitée lorsque
    <span class="function"><a href="function.isset.php" class="function">isset()</a></span> ou <span class="function"><a href="function.empty.php" class="function">empty()</a></span> sont appelées sur
    des propriétés inaccessibles (protégées ou privées) ou non existantes.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.unset" class="link">__unset()</a> est invoquée lorsque
    <span class="function"><a href="function.unset.php" class="function">unset()</a></span> est appelée sur des propriétés inaccessibles
    (protégées ou privées) ou non existantes.
   </p>

   <p class="para">
    L&#039;argument <var class="varname">$name</var> est le nom de la propriété avec laquelle on interagit.
    L&#039;argument <var class="varname">$value</var> de la méthode <a href="language.oop5.overloading.php#object.set" class="link">__set()</a>
    spécifie la valeur à laquelle la propriété <var class="varname">$name</var> devrait être définie.
   </p>

   <p class="para">
    La surcharge de propriétés ne fonctionne que dans les contextes objets.
    Ces méthodes magiques ne seront pas lancées en contexte statique.
    Par conséquent, ces méthodes ne devraient pas être déclarées comme
    <a href="language.oop5.static.php" class="link">statiques</a>.
    Un avertissement est levé si une des méthodes magiques est déclarée comme statique.
   </p>

   <blockquote class="note"><p><strong class="note">Note</strong>: 
    <p class="para">
     La valeur retournée par <a href="language.oop5.overloading.php#object.set" class="link">__set()</a>
     est ignorée en raison de la façon dont PHP traite l&#039;opérateur d&#039;affectation.
     De la même façon, <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> n&#039;est jamais appelée lors
     d&#039;un enchaînement d&#039;affectation, comme ceci :
     <code class="literal"><div class="annotation-interactive cdata"><pre> $a = $obj-&gt;b = 8; </pre></div></code>
    </p>
   </p></blockquote>

   <blockquote class="note"><p><strong class="note">Note</strong>: 
    <p class="para">
     PHP n&#039;appellera pas une méthode surchargée à partir de la même méthode surchargée.
     Cela signifie, par exemple, qu&#039;écrire <code class="code">return $this-&gt;foo</code> à l&#039;intérieur
     de <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> retournera <code class="literal">null</code>
     et lèvera un <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> s&#039;il n&#039;y a pas de propriété <code class="literal">foo</code> définie,
     plutôt que d&#039;appeler <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> une deuxième fois.
     Toutefois, les méthodes de surcharge peuvent invoquer d&#039;autres méthodes de surcharge de manière implicite
     (par exemple, <a href="language.oop5.overloading.php#object.set" class="link">__set()</a> déclenchant <a href="language.oop5.overloading.php#object.get" class="link">__get()</a>).
    </p>
   </p></blockquote>

   <div class="example" id="example-1">
    <p><strong>Exemple #1 Exemple de surcharge de propriétés avec les méthodes
     <a href="language.oop5.overloading.php#object.get" class="link">__get()</a>,
     <a href="language.oop5.overloading.php#object.set" class="link">__set()</a>,
     <a href="language.oop5.overloading.php#object.isset" class="link">__isset()</a> et
     <a href="language.oop5.overloading.php#object.unset" class="link">__unset()</a>
    </strong></p>
    <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">PropertyTest<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">/**  Variable pour les données surchargées.  */<br />    </span><span style="color: #007700">private </span><span style="color: #0000BB">$data </span><span style="color: #007700">= array();<br /><br />    </span><span style="color: #FF8000">/**  La surcharge n'est pas utilisée sur les propriétés déclarées.  */<br />    </span><span style="color: #007700">public </span><span style="color: #0000BB">$declared </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /><br />    </span><span style="color: #FF8000">/**  La surcharge n'est lancée que lorsque l'on accède à cette propriété depuis l'extérieur de la classe.  */<br />    </span><span style="color: #007700">private </span><span style="color: #0000BB">$hidden </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__set</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$value</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #DD0000">"Définition de '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' à la valeur '</span><span style="color: #0000BB">$value</span><span style="color: #DD0000">'\n"</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">] = </span><span style="color: #0000BB">$value</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">__get</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #DD0000">"Récupération de '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">'\n"</span><span style="color: #007700">;<br />        if (</span><span style="color: #0000BB">array_key_exists</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data</span><span style="color: #007700">)) {<br />            return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">];<br />        }<br /><br />        </span><span style="color: #0000BB">$trace </span><span style="color: #007700">= </span><span style="color: #0000BB">debug_backtrace</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">trigger_error</span><span style="color: #007700">(<br />            </span><span style="color: #DD0000">'Propriété non-définie via __get() : ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$name </span><span style="color: #007700">.<br />            </span><span style="color: #DD0000">' dans ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$trace</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'file'</span><span style="color: #007700">] .<br />            </span><span style="color: #DD0000">' à la ligne ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$trace</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][</span><span style="color: #DD0000">'line'</span><span style="color: #007700">],<br />            </span><span style="color: #0000BB">E_USER_NOTICE</span><span style="color: #007700">);<br />        return </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">__isset</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #DD0000">"Est-ce que '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' est défini ?\n"</span><span style="color: #007700">;<br />        return isset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">]);<br />    }<br /><br />    public function </span><span style="color: #0000BB">__unset</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #DD0000">"Effacement de '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">'\n"</span><span style="color: #007700">;<br />        unset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">data</span><span style="color: #007700">[</span><span style="color: #0000BB">$name</span><span style="color: #007700">]);<br />    }<br /><br />    </span><span style="color: #FF8000">/**  Ce n'est pas une méthode magique, nécessaire ici que pour l'exemple.  */<br />    </span><span style="color: #007700">public function </span><span style="color: #0000BB">getHidden</span><span style="color: #007700">()<br />    {<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">hidden</span><span style="color: #007700">;<br />    }<br />}<br /><br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">PropertyTest</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">a </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">a </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(isset(</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">a</span><span style="color: #007700">));<br />unset(</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">a</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(isset(</span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">a</span><span style="color: #007700">));<br />echo </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /><br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">declared </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n\n"</span><span style="color: #007700">;<br /><br />echo </span><span style="color: #DD0000">"Manipulons maintenant la propriété privée nommée 'hidden' :\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #DD0000">"'hidden' est visible depuis la classe, donc __get() n'est pas utilisée...\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getHidden</span><span style="color: #007700">() . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #DD0000">"'hidden' n'est pas visible en dehors de la classe, donc __get() est utilisée...\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">hidden </span><span style="color: #007700">. </span><span style="color: #DD0000">"\n"</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="annotation-interactive cdata"><pre>
Définition de &#039;a&#039; à la valeur &#039;1&#039;
Récupération de &#039;a&#039;
1

Est-ce que &#039;a&#039; est défini ?
bool(true)
Effacement de &#039;a&#039;
Est-ce que &#039;a&#039; est défini ?
bool(false)

1

Manipulons maintenant la propriété privée nommée &#039;hidden&#039; :
&#039;hidden&#039; est visible depuis la classe, donc __get() n&#039;est pas utilisée...
2
&#039;hidden&#039; n&#039;est pas visible en dehors de la classe, donc __get() est utilisée...
Récupération de &#039;hidden&#039;


Notice: Propriété non-définie via __get() : hidden dans &lt;file&gt; à la ligne 70 dans &lt;file&gt; à la ligne 29
</pre></div>
    </div>

   </div>
  </div>

  <div class="sect2" id="language.oop5.overloading.methods">
   <h3 class="title">Surcharge de méthodes</h3>

   <div class="methodsynopsis dc-description" id="object.call">
    <span class="modifier">public</span> <span class="methodname"><strong>__call</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.string.php" class="type string">string</a></span> <code class="parameter">$name</code></span>, <span class="methodparam"><span class="type"><a href="language.types.array.php" class="type array">array</a></span> <code class="parameter">$arguments</code></span>): <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span></div>

   <div class="methodsynopsis dc-description" id="object.callstatic"><span class="modifier">public static</span> <span class="methodname"><strong>__callStatic</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.string.php" class="type string">string</a></span> <code class="parameter">$name</code></span>, <span class="methodparam"><span class="type"><a href="language.types.array.php" class="type array">array</a></span> <code class="parameter">$arguments</code></span>): <span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span></div>


   <p class="para">
    <a href="language.oop5.overloading.php#object.call" class="link">__call()</a> est appelée lorsque l&#039;on invoque des
    méthodes inaccessibles dans un contexte objet.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.callstatic" class="link">__callStatic()</a> est lancée lorsque l&#039;on invoque
    des méthodes inaccessibles dans un contexte statique.
   </p>

   <p class="para">
    L&#039;argument <var class="varname">$name</var> est le nom de la méthode appelée.
    L&#039;argument <var class="varname">$arguments</var> est un tableau contenant
    les paramètres passés à la méthode <var class="varname">$name</var>.
   </p>

   <div class="example" id="example-2">
    <p><strong>Exemple #2 Surcharge de méthodes avec
     <a href="language.oop5.overloading.php#object.call" class="link">__call()</a> et
     <a href="language.oop5.overloading.php#object.callstatic" class="link">__callStatic()</a></strong></p>
    <div class="example-contents">
  <div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MethodTest<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__call</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #FF8000">// Note : la valeur de $name est sensible à la casse.<br />        </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Appel de la méthode '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' "<br />             </span><span style="color: #007700">. </span><span style="color: #0000BB">implode</span><span style="color: #007700">(</span><span style="color: #DD0000">', '</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">). </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br /><br />    public static function </span><span style="color: #0000BB">__callStatic</span><span style="color: #007700">(</span><span style="color: #0000BB">$name</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #FF8000">// Note : la valeur de $name est sensible à la casse.<br />        </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Appel de la méthode statique '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' "<br />             </span><span style="color: #007700">. </span><span style="color: #0000BB">implode</span><span style="color: #007700">(</span><span style="color: #DD0000">', '</span><span style="color: #007700">, </span><span style="color: #0000BB">$arguments</span><span style="color: #007700">). </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">MethodTest</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">runTest</span><span style="color: #007700">(</span><span style="color: #DD0000">'dans un contexte objet'</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">MethodTest</span><span style="color: #007700">::</span><span style="color: #0000BB">runTest</span><span style="color: #007700">(</span><span style="color: #DD0000">'dans un contexte statique'</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="annotation-interactive cdata"><pre>
Appel de la méthode &#039;runTest&#039; dans un contexte objet
Appel de la méthode statique &#039;runTest&#039; dans un contexte statique
</pre></div>
    </div>
   </div>

  </div>

 </div><?php manual_footer($setup); ?>