<?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 => 'es',
  ),
  'this' => 
  array (
    0 => 'language.oop5.overloading.php',
    1 => 'Sobrecarga m&aacute;gica',
    2 => 'Sobrecarga m&aacute;gica',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Clases y objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.anonymous.php',
    1 => 'Clases an&oacute;nimas',
  ),
  'next' => 
  array (
    0 => 'language.oop5.iterations.php',
    1 => 'Recorrido de objetos',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    '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">Sobrecarga mágica</h2>

  <p class="para">
   La sobrecarga mágica en PHP permite <q class="quote">crear</q> dinámicamente propiedades y métodos. Estas entidades dinámicas son
   tratadas a través de métodos mágicos establecidos que se pueden posicionar
   en una clase para diversos tipos de acciones.
  </p>

  <p class="para">
   Los métodos mágicos de sobrecarga son llamados durante la interacción
   con propiedades o métodos que no han sido declarados
   o no son <a href="language.oop5.visibility.php" class="link">visibles</a>
   en el contexto actual. El resto de esta sección utiliza
   los términos de <q class="quote">propiedades inaccesibles</q> y de
   <q class="quote">métodos inaccesibles</q> para referirse a esta
   combinación de declaración y visibilidad.
  </p>

  <p class="para">
   Todos los métodos mágicos de sobrecarga deben ser definidos como
   <code class="literal">public</code>.
  </p>

  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    Ninguno de los argumentos de estos métodos mágicos puede ser
    <a href="functions.arguments.php#functions.arguments.by-reference" class="link">pasado por
    referencia</a>.
   </p>
  </p></blockquote>

  <blockquote class="note"><p><strong class="note">Nota</strong>: 
   <p class="para">
    La interpretación PHP de la <q class="quote">sobrecarga</q> es
    diferente de la de la mayoría de los lenguajes orientados a objetos. La sobrecarga, habitualmente, proporciona la posibilidad de tener
    varios métodos con el mismo nombre pero con una cantidad
    y tipos diferentes de argumentos.
   </p>
  </p></blockquote>

  <div class="sect2" id="language.oop5.overloading.members">
   <h3 class="title">Sobrecarga de propiedades</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> es solicitada al escribir datos
    hacia propiedades inaccesibles (protegidas o privadas) o no existentes.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> es llamada para leer datos desde
    propiedades inaccesibles (protegidas o privadas) o no existentes.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.isset" class="link">__isset()</a> es solicitada cuando
    <span class="function"><a href="function.isset.php" class="function">isset()</a></span> o <span class="function"><a href="function.empty.php" class="function">empty()</a></span> son llamadas sobre
    propiedades inaccesibles (protegidas o privadas) o no existentes.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.unset" class="link">__unset()</a> es invocada cuando
    <span class="function"><a href="function.unset.php" class="function">unset()</a></span> es llamada sobre propiedades inaccesibles
    (protegidas o privadas) o no existentes.
   </p>

   <p class="para">
    El argumento <var class="varname">$name</var> es el nombre de la propiedad con la que se interactúa.
    El argumento del método <a href="language.oop5.overloading.php#object.set" class="link">__set()</a> <var class="varname">$value</var>
    especifica el valor al que la propiedad <var class="varname">$name</var> debería ser definida.
   </p>

   <p class="para">
    La sobrecarga de propiedades solo funciona en contextos de objeto.
    Estos métodos mágicos no serán lanzados en contexto estático.
    Por consiguiente, estos métodos no deberían ser declarados como
    <a href="language.oop5.static.php" class="link">estáticos</a>.
    Se lanza un aviso si alguno de los métodos mágicos es declarado como <code class="literal">static</code>.
   </p>

   <blockquote class="note"><p><strong class="note">Nota</strong>: 
    <p class="para">
     El valor devuelto por <a href="language.oop5.overloading.php#object.set" class="link">__set()</a>
     es ignorado debido a la forma en que PHP trata el operador de asignación.
     De la misma manera, <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> nunca es llamada durante
     una asignación encadenada, como esta:
     <code class="literal"><div class="cdata"><pre> $a = $obj-&gt;b = 8; </pre></div></code>
    </p>
   </p></blockquote>

   <blockquote class="note"><p><strong class="note">Nota</strong>: 
    <p class="para">
     PHP no llamará a un método sobrecargado desde el mismo método sobrecargado.
     Esto significa, por ejemplo, que escribir <code class="code">return $this-&gt;foo</code> dentro
     de <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> devolverá <code class="literal">null</code>
     y lanzará un <strong><code><a href="errorfunc.constants.php#constant.e-warning">E_WARNING</a></code></strong> si no hay una propiedad <code class="literal">foo</code> definida,
     en lugar de llamar a <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> una segunda vez.
     Sin embargo, los métodos de sobrecarga pueden invocar otros métodos de sobrecarga de manera implícita
     (por ejemplo, <a href="language.oop5.overloading.php#object.set" class="link">__set()</a> desencadenando <a href="language.oop5.overloading.php#object.get" class="link">__get()</a>).
    </p>
   </p></blockquote>

   <div class="example" id="example-1">
    <p><strong>Ejemplo #1 Ejemplo de sobrecarga de propiedades con los métodos
     <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> y
     <a href="language.oop5.overloading.php#object.unset" class="link">__unset()</a>
    </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">class </span><span style="color: #0000BB">PropertyTest<br /></span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">/**  Variable para los datos sobrecargados.  */<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 sobrecarga no es utilizada en las propiedades declaradas.  */<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 sobrecarga solo es lanzada cuando se accede a esta propiedad desde fuera de la clase.  */<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">"Definición de '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' al valor '</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">"Recuperación 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">'Propiedad no definida vía __get() : ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$name </span><span style="color: #007700">.<br />            </span><span style="color: #DD0000">' en ' </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">' en la línea ' </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á '</span><span style="color: #0000BB">$name</span><span style="color: #DD0000">' definido?\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">"Borrado 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">/**  Este no es un método mágico, necesario aquí solo para el ejemplo.  */<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 /></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">"Manipulemos ahora la propiedad privada llamada 'hidden' :\n"</span><span style="color: #007700">;<br />echo </span><span style="color: #DD0000">"'hidden' es visible desde la clase, por lo que __get() no es utilizado...\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' no es visible fuera de la clase, por lo que __get() es utilizado...\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>El ejemplo anterior mostrará:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
Definición de &#039;a&#039; a &#039;1&#039;
Recuperación de &#039;a&#039;
1

¿Está &#039;a&#039; definido?
bool(true)
Borrado de &#039;a&#039;
¿Está &#039;a&#039; definido?
bool(false)

1

Manipulemos ahora la propiedad privada llamada &#039;hidden&#039; :
&#039;hidden&#039; es visible desde la clase, por lo que __get() no es utilizado...
2
&#039;hidden&#039; no es visible fuera de la clase, por lo que __get() es utilizado...
Recuperación de &#039;hidden&#039;


Notice: Propiedad no definida vía __get() : hidden en &lt;file&gt; en la línea 64 en &lt;file&gt; en la línea 28
</pre></div>
    </div>

   </div>
  </div>

  <div class="sect2" id="language.oop5.overloading.methods">
   <h3 class="title">Sobrecarga de métodos</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> es llamada cuando se invoca
    métodos inaccesibles en un contexto de objeto.
   </p>

   <p class="para">
    <a href="language.oop5.overloading.php#object.callstatic" class="link">__callStatic()</a> es lanzada cuando se invoca
    métodos inaccesibles en un contexto estático.
   </p>

   <p class="para">
    El argumento <var class="varname">$name</var> es el nombre del método llamado.
    El argumento <var class="varname">$arguments</var> es un array que contiene
    los parámetros pasados al método <var class="varname">$name</var>.
   </p>

   <div class="example" id="example-2">
    <p><strong>Ejemplo #2 Sobrecarga de métodos con
     <a href="language.oop5.overloading.php#object.call" class="link">__call()</a> y
     <a href="language.oop5.overloading.php#object.callstatic" class="link">__callStatic()</a></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">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">// Nota: el valor de $name es sensible a mayúsculas y minúsculas.<br />        </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Llamada al método '</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">// Nota: el valor de $name es sensible a mayúsculas y minúsculas.<br />        </span><span style="color: #007700">echo </span><span style="color: #DD0000">"Llamada al método estático '</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">'en un contexto de objeto'</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">'en un contexto static'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

    <div class="example-contents"><p>El ejemplo anterior mostrará:</p></div>
    <div class="example-contents screen">
<div class="cdata"><pre>
Llamada al método &#039;runTest&#039; en un contexto de objeto
Llamada al método estático &#039;runTest&#039; en un contexto static
</pre></div>
    </div>
   </div>

  </div>

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