<?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.late-static-bindings.php',
    1 => 'Late Static Bindings (Resoluci&oacute;n est&aacute;tica en tiempo de ejecuci&oacute;n)',
    2 => 'Late Static Bindings (Resoluci&oacute;n est&aacute;tica en tiempo de ejecuci&oacute;n)',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'Clases y objetos',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.object-comparison.php',
    1 => 'Comparaci&oacute;n de objetos',
  ),
  'next' => 
  array (
    0 => 'language.oop5.references.php',
    1 => 'Objetos y referencias',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    'path' => 'language/oop5/late-static-bindings.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.late-static-bindings" class="sect1">
  <h2 class="title">Late Static Bindings (Resolución estática en tiempo de ejecución)</h2>
  <p class="para">
   PHP implementa una funcionalidad llamada
   late static binding, en español la resolución
   estática en tiempo de ejecución, que puede ser utilizada para referenciar la clase llamada
   en un contexto de herencia estática.
  </p>

  <p class="para">
   Más precisamente, las resoluciones estáticas en tiempo de ejecución funcionan registrando
   el nombre de la clase en la última &quot;llamada no reenviada&quot;. En el caso de las llamadas de
   métodos estáticos, se trata de la clase explícitamente nombrada (generalmente, la que está a
   la izquierda del operador
   <a href="language.oop5.paamayim-nekudotayim.php" class="link"><code class="literal">::</code></a>) ;
   en el caso de métodos no estáticos, se trata de la clase del objeto. Una &quot;llamada
   reenviada&quot; es una llamada estática introducida por <code class="literal">self::</code>,
   <code class="literal">parent::</code>, <code class="literal">static::</code>, o, subiendo en la
   jerarquía de clases, <span class="function"><a href="function.forward-static-call.php" class="function">forward_static_call()</a></span>.
   

   La función <span class="function"><a href="function.get-called-class.php" class="function">get_called_class()</a></span> puede ser utilizada para recuperar
   una cadena que contiene el nombre de la clase llamada, y <code class="literal">static::</code>
   introduce su ámbito.
  </p>

  <p class="para">
   Esta funcionalidad ha sido bautizada como &quot;late static bindings&quot;,
   con un punto de vista interno. &quot;Late binding&quot;, literalmente
   resolución tardía, proviene del hecho de que los elementos <code class="literal">static::</code>
   no serán resueltos utilizando la clase donde el método ha sido definido, sino
   que será calculada utilizando la información en tiempo de ejecución.
   También se denomina &quot;static binding&quot; ya que puede ser utilizado para (sin estar
   limitado a) los métodos estáticos.
  </p>

  <div class="sect2" id="language.oop5.late-static-bindings.self">
   <h3 class="title">Limitaciones de <code class="literal">self::</code></h3>
   <p class="para">
    Las referencias estáticas a la clase actual, con <code class="literal">self::</code> o
    <code class="literal">__CLASS__</code>, son resueltas utilizando la clase a la que
    pertenecen las funciones, es decir, donde fueron definidas:
   </p>
   <div class="example" id="example-1">
    <p><strong>Ejemplo #1 Uso de <code class="literal">self::</code></strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">__CLASS__</span><span style="color: #007700">;<br />    }<br /><br />    public static function </span><span style="color: #0000BB">test</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">who</span><span style="color: #007700">();<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />         echo </span><span style="color: #0000BB">__CLASS__</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">test</span><span style="color: #007700">();<br /><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>
A
</pre></div>
    </div>
   </div>

  </div>

  <div class="sect2" id="language.oop5.late-static-bindings.usage">
   <h3 class="title">Uso de la resolución estática en tiempo de ejecución</h3>

   <p class="para">
    La resolución estática en tiempo de ejecución intenta superar esta limitación
    introduciendo una palabra clave que hace referencia a la clase
    que ha sido llamada durante la ejecución. Para simplificar, esta palabra clave
    permite la referencia a <code class="literal">B</code> desde
    <code class="literal">test()</code>, en el ejemplo anterior.
    Se decidió no introducir una nueva palabra clave, sino más bien
    utilizar la palabra <code class="literal">static</code> que ya estaba
    reservada.
   </p>

   <div class="example" id="example-2">
    <p><strong>Ejemplo #2 Uso simple de <code class="literal">static::</code></strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">__CLASS__</span><span style="color: #007700">;<br />    }<br /><br />    public static function </span><span style="color: #0000BB">test</span><span style="color: #007700">()<br />    {<br />        static::</span><span style="color: #0000BB">who</span><span style="color: #007700">(); </span><span style="color: #FF8000">// Aquí, resolución estática en tiempo de ejecución<br />    </span><span style="color: #007700">}<br />}<br /><br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />         echo </span><span style="color: #0000BB">__CLASS__</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">B</span><span style="color: #007700">::</span><span style="color: #0000BB">test</span><span style="color: #007700">();<br /><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>
B
</pre></div>
    </div>
   </div>
   <blockquote class="note"><p><strong class="note">Nota</strong>: 
    <p class="para">
     En contextos no estáticos, la clase llamada será la del objeto.
     Como <code class="literal">$this-&gt;</code> intentará llamar
     a métodos privados desde el mismo ámbito, utilizar <code class="literal">static::</code>
     podría dar resultados diferentes. Tenga en cuenta también que
     <code class="literal">static::</code> solo puede hacer referencia a propiedades
     estáticas.
    </p>
   </p></blockquote>
   <div class="example" id="example-3">
    <p><strong>Ejemplo #3 Uso de <code class="literal">static::</code> en un contexto no estático</strong></p>
    <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    private function </span><span style="color: #0000BB">foo</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #DD0000">"Success!\n"</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">test</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br />        static::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />   </span><span style="color: #FF8000">/* foo() será copiada en B, por lo tanto su ámbito será siempre A<br />    * y la llamada se realizará sin problemas */<br /></span><span style="color: #007700">}<br /><br />class </span><span style="color: #0000BB">C </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    private function </span><span style="color: #0000BB">foo</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #FF8000">/* El método original es reemplazado; el ámbito es el de C */<br />    </span><span style="color: #007700">}<br />}<br /><br /></span><span style="color: #0000BB">$b </span><span style="color: #007700">= new </span><span style="color: #0000BB">B</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$b</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">test</span><span style="color: #007700">();<br /><br /></span><span style="color: #0000BB">$c </span><span style="color: #007700">= new </span><span style="color: #0000BB">C</span><span style="color: #007700">();<br />try {<br />    </span><span style="color: #0000BB">$c</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">test</span><span style="color: #007700">();<br />} catch (</span><span style="color: #0000BB">Error $e</span><span style="color: #007700">) {<br />    echo </span><span style="color: #0000BB">$e</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getMessage</span><span style="color: #007700">();<br />}<br /><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>
Success!
Success!
Success!
Call to private method C::foo() from scope A
</pre></div>
    </div>
   </div>
   <blockquote class="note"><p><strong class="note">Nota</strong>: 
    <p class="para">
     La resolución de estáticos en tiempo de ejecución se detendrá en una llamada estática
     completamente resuelta. Por otro lado, las llamadas estáticas utilizando
     una palabra clave como <code class="literal">parent::</code> o <code class="literal">self::</code>
     reenviarán la información de llamada.
    </p>
    <div class="example" id="example-4">
     <p><strong>Ejemplo #4 Llamadas con o sin reenvío</strong></p>
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">foo</span><span style="color: #007700">()<br />    {<br />        static::</span><span style="color: #0000BB">who</span><span style="color: #007700">();<br />    }<br /><br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">__CLASS__</span><span style="color: #007700">.</span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">B </span><span style="color: #007700">extends </span><span style="color: #0000BB">A<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">test</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">A</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br />        </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">foo</span><span style="color: #007700">();<br />    }<br /><br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">__CLASS__</span><span style="color: #007700">.</span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br />class </span><span style="color: #0000BB">C </span><span style="color: #007700">extends </span><span style="color: #0000BB">B<br /></span><span style="color: #007700">{<br />    public static function </span><span style="color: #0000BB">who</span><span style="color: #007700">()<br />    {<br />        echo </span><span style="color: #0000BB">__CLASS__</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">C</span><span style="color: #007700">::</span><span style="color: #0000BB">test</span><span style="color: #007700">();<br /><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>
A
C
C
</pre></div>
     </div>
    </div>
   </p></blockquote>
  </div>
</div><?php manual_footer($setup); ?>