<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.functions.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'es',
  ),
  'this' => 
  array (
    0 => 'functions.anonymous.php',
    1 => 'Funciones an&oacute;nimas',
    2 => 'Funciones an&oacute;nimas',
  ),
  'up' => 
  array (
    0 => 'language.functions.php',
    1 => 'Las funciones',
  ),
  'prev' => 
  array (
    0 => 'functions.internal.php',
    1 => 'Funciones internas',
  ),
  'next' => 
  array (
    0 => 'functions.arrow.php',
    1 => 'Funci&oacute;n Flecha',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'es',
    'path' => 'language/functions.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="functions.anonymous" class="sect1">
  <h2 class="title">Funciones anónimas</h2>
  <p class="simpara">
   Las funciones anónimas, también conocidas como <code class="literal">closures</code>,
   permiten la creación de funciones sin especificar su nombre.
   Son particularmente útiles como funciones de devolución de llamada <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span>,
   pero su utilización no se limita a este único uso.
  </p>
  <p class="simpara">
   Las funciones anónimas están implementadas utilizando la clase
   <a href="class.closure.php" class="link"><span class="classname"><a href="class.closure.php" class="classname">Closure</a></span></a>.
  </p>

  <div class="example" id="example-1">
   <p><strong>Ejemplo #1 Ejemplos con funciones anónimas</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">echo </span><span style="color: #0000BB">preg_replace_callback</span><span style="color: #007700">(</span><span style="color: #DD0000">'~-([a-z])~'</span><span style="color: #007700">, function (</span><span style="color: #0000BB">$match</span><span style="color: #007700">) {<br />    return </span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(</span><span style="color: #0000BB">$match</span><span style="color: #007700">[</span><span style="color: #0000BB">1</span><span style="color: #007700">]);<br />}, </span><span style="color: #DD0000">'hola-mundo'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>

  <p class="simpara">
   Las funciones anónimas también pueden ser utilizadas como valores de
   variables. PHP convertirá automáticamente estas expresiones
   en objetos <span class="classname"><a href="class.closure.php" class="classname">Closure</a></span>. Asignar un closure
   a una variable es lo mismo que una asignación clásica,
   incluyendo el punto y coma final.
  </p>

  <div class="example" id="example-2">
   <p><strong>Ejemplo #2 Asignación de función anónima a una variable</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$saludo </span><span style="color: #007700">= function(</span><span style="color: #0000BB">$name</span><span style="color: #007700">) {<br />    </span><span style="color: #0000BB">printf</span><span style="color: #007700">(</span><span style="color: #DD0000">"Hola %s\r\n"</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br />};<br /><br /></span><span style="color: #0000BB">$saludo</span><span style="color: #007700">(</span><span style="color: #DD0000">'Mundo'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$saludo</span><span style="color: #007700">(</span><span style="color: #DD0000">'PHP'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>

  <p class="simpara">
   Las funciones anónimas pueden heredar variables del contexto de su
   padre. Estas variables deben entonces ser pasadas en la construcción
   de lenguaje <code class="literal">use</code>.
   A partir de PHP 7.1, estas variables no deben incluir <a href="language.variables.predefined.php" class="link">superglobals</a>,
   <var class="varname">$this</var>, o variables con el mismo nombre que un
   parámetro. Una declaración de tipo de retorno para la función debe ser colocada
   <em>después</em> de la cláusula <code class="literal">use</code>.
  </p>

  <div class="example" id="example-3">
   <p><strong>Ejemplo #3 Herencia de variable desde el contexto padre</strong></p>
   <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$message </span><span style="color: #007700">= </span><span style="color: #DD0000">'hola'</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// Sin "use"<br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= function () {<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$message</span><span style="color: #007700">);<br />};<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// Hereda $message<br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= function () use (</span><span style="color: #0000BB">$message</span><span style="color: #007700">) {<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$message</span><span style="color: #007700">);<br />};<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// El valor de la variable heredada es definido cuando la función es<br />// definida no cuando es llamada<br /></span><span style="color: #0000BB">$message </span><span style="color: #007700">= </span><span style="color: #DD0000">'mundo'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// Reinicialización de la variable message<br /></span><span style="color: #0000BB">$message </span><span style="color: #007700">= </span><span style="color: #DD0000">'hola'</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// Herencia por referencia<br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= function () use (&amp;</span><span style="color: #0000BB">$message</span><span style="color: #007700">) {<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$message</span><span style="color: #007700">);<br />};<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// El cambio de valor en el contexto padre es reflejado al<br />// llamar a la función.<br /></span><span style="color: #0000BB">$message </span><span style="color: #007700">= </span><span style="color: #DD0000">'mundo'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// Las funciones anónimas también aceptan argumentos clásicos<br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= function (</span><span style="color: #0000BB">$arg</span><span style="color: #007700">) use (</span><span style="color: #0000BB">$message</span><span style="color: #007700">) {<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$arg </span><span style="color: #007700">. </span><span style="color: #DD0000">' ' </span><span style="color: #007700">. </span><span style="color: #0000BB">$message</span><span style="color: #007700">);<br />};<br /></span><span style="color: #0000BB">$example</span><span style="color: #007700">(</span><span style="color: #DD0000">"hola"</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// Declaración de tipo de retorno viene después de la cláusula use<br /></span><span style="color: #0000BB">$example </span><span style="color: #007700">= function () use (</span><span style="color: #0000BB">$message</span><span style="color: #007700">): </span><span style="color: #0000BB">string </span><span style="color: #007700">{<br />    return </span><span style="color: #DD0000">"hola </span><span style="color: #0000BB">$message</span><span style="color: #DD0000">"</span><span style="color: #007700">;<br />};<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$example</span><span style="color: #007700">());<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>Resultado del ejemplo anterior es similar a:</p></div>
   <div class="example-contents screen">
<div class="cdata"><pre>
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) &quot;hola&quot;
string(5) &quot;hola&quot;
string(5) &quot;hola&quot;
string(5) &quot;mundo&quot;
string(11) &quot;hola mundo&quot;
string(11) &quot;hola mundo&quot;
</pre></div>
   </div>
  </div>

  <p class="para">
   A partir de PHP 8.0.0, la lista de variables heredadas del contexto puede
   incluir una coma final, que será ignorada.
  </p>
  <p class="simpara">
   La herencia del contexto padre
   <em>no es</em> lo mismo que las variables
   del entorno global. Las variables globales existen en el
   contexto global, que es el mismo, independientemente de la función que
   se esté ejecutando. El contexto padre de una función anónima es la función
   en la que la función fue declarada (no necesariamente la que llama). Véase el ejemplo siguiente:
  </p>

  <div class="example" id="example-4">
   <p><strong>Ejemplo #4 Funciones anónimas y contexto</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">// Un carrito de compra simple, que contiene una lista de productos<br />// seleccionados y la cantidad deseada de cada producto. Incluye<br />// un método que calcula el precio total de los elementos en el carrito<br />// utilizando una función de devolución de llamada anónima.<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Carrito<br /></span><span style="color: #007700">{<br />    const </span><span style="color: #0000BB">PRECIO_MANTEQUILLA  </span><span style="color: #007700">= </span><span style="color: #0000BB">1.00</span><span style="color: #007700">;<br />    const </span><span style="color: #0000BB">PRECIO_LECHE    </span><span style="color: #007700">= </span><span style="color: #0000BB">3.00</span><span style="color: #007700">;<br />    const </span><span style="color: #0000BB">PRECIO_HUEVO    </span><span style="color: #007700">= </span><span style="color: #0000BB">6.95</span><span style="color: #007700">;<br /><br />    protected </span><span style="color: #0000BB">$products </span><span style="color: #007700">= array();<br /><br />    public function </span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #0000BB">$product</span><span style="color: #007700">, </span><span style="color: #0000BB">$quantity</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">products</span><span style="color: #007700">[</span><span style="color: #0000BB">$product</span><span style="color: #007700">] = </span><span style="color: #0000BB">$quantity</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">getQuantity</span><span style="color: #007700">(</span><span style="color: #0000BB">$product</span><span style="color: #007700">)<br />    {<br />        return isset(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">products</span><span style="color: #007700">[</span><span style="color: #0000BB">$product</span><span style="color: #007700">]) ? </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">products</span><span style="color: #007700">[</span><span style="color: #0000BB">$product</span><span style="color: #007700">] :<br />               </span><span style="color: #0000BB">FALSE</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">getTotal</span><span style="color: #007700">(</span><span style="color: #0000BB">$tax</span><span style="color: #007700">)<br />    {<br />        </span><span style="color: #0000BB">$total </span><span style="color: #007700">= </span><span style="color: #0000BB">0.00</span><span style="color: #007700">;<br /><br />        </span><span style="color: #0000BB">$callback </span><span style="color: #007700">=<br />            function (</span><span style="color: #0000BB">$quantity</span><span style="color: #007700">, </span><span style="color: #0000BB">$product</span><span style="color: #007700">) use (</span><span style="color: #0000BB">$tax</span><span style="color: #007700">, &amp;</span><span style="color: #0000BB">$total</span><span style="color: #007700">)<br />            {<br />                </span><span style="color: #0000BB">$pricePerItem </span><span style="color: #007700">= </span><span style="color: #0000BB">constant</span><span style="color: #007700">(</span><span style="color: #0000BB">__CLASS__ </span><span style="color: #007700">. </span><span style="color: #DD0000">"::PRECIO_" </span><span style="color: #007700">.<br />                    </span><span style="color: #0000BB">strtoupper</span><span style="color: #007700">(</span><span style="color: #0000BB">$product</span><span style="color: #007700">));<br />                </span><span style="color: #0000BB">$total </span><span style="color: #007700">+= (</span><span style="color: #0000BB">$pricePerItem </span><span style="color: #007700">* </span><span style="color: #0000BB">$quantity</span><span style="color: #007700">) * (</span><span style="color: #0000BB">$tax </span><span style="color: #007700">+ </span><span style="color: #0000BB">1.0</span><span style="color: #007700">);<br />            };<br /><br />        </span><span style="color: #0000BB">array_walk</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">products</span><span style="color: #007700">, </span><span style="color: #0000BB">$callback</span><span style="color: #007700">);<br />        return </span><span style="color: #0000BB">round</span><span style="color: #007700">(</span><span style="color: #0000BB">$total</span><span style="color: #007700">, </span><span style="color: #0000BB">2</span><span style="color: #007700">);<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$mi_carrito </span><span style="color: #007700">= new </span><span style="color: #0000BB">Carrito</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// Añadir elementos al carrito<br /></span><span style="color: #0000BB">$mi_carrito</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #DD0000">'mantequilla'</span><span style="color: #007700">, </span><span style="color: #0000BB">1</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mi_carrito</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #DD0000">'leche'</span><span style="color: #007700">, </span><span style="color: #0000BB">3</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$mi_carrito</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">add</span><span style="color: #007700">(</span><span style="color: #DD0000">'huevo'</span><span style="color: #007700">, </span><span style="color: #0000BB">6</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// Mostrar el precio con 5.5% de IVA<br /></span><span style="color: #007700">print </span><span style="color: #0000BB">$mi_carrito</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getTotal</span><span style="color: #007700">(</span><span style="color: #0000BB">0.055</span><span style="color: #007700">) . </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// El resultado será 54.29<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>

  <div class="example" id="example-5">
   <p><strong>Ejemplo #5 Vinculación automática de <code class="literal">$this</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">Test<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">testing</span><span style="color: #007700">()<br />    {<br />        return function() {<br />            </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">);<br />        };<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$object </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$function </span><span style="color: #007700">= </span><span style="color: #0000BB">$object</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">testing</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$function</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>
object(Test)#1 (0) {
}
</pre></div>
    </div>
  </div>

  <p class="para">
   Cuando se declara en el contexto de una clase, la clase
   actual es automáticamente vinculada, haciéndola <code class="literal">$this</code>
   disponible en el contexto de la función. Si este vínculo automático de
   la clase actual no es deseado, entonces las
   <a href="functions.anonymous.php#functions.anonymous-functions.static" class="link">funciones anónimas
    estáticas</a> pueden ser utilizadas en su lugar.
  </p>

  <div class="sect2" id="functions.anonymous-functions.static">
   <h3 class="title">Las funciones anónimas estáticas</h3>
   <p class="para">
    Las funciones anónimas pueden ser declaradas estáticamente.
    Esto permite no vincular automáticamente la clase actual a la función.
    Los objetos también pueden no ser vinculados durante la ejecución.
   </p>
   <p class="para">
    <div class="example" id="example-6">
     <p><strong>Ejemplo #6 Intento de uso de <code class="literal">$this</code> en una función anónima estática</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">Foo<br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">()<br />    {<br />        </span><span style="color: #0000BB">$func </span><span style="color: #007700">= static function() {<br />            </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">);<br />        };<br />        </span><span style="color: #0000BB">$func</span><span style="color: #007700">();<br />    }<br />};<br />new </span><span style="color: #0000BB">Foo</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>
Notice: Undefined variable: this in %s on line %d
NULL
</pre></div>
      </div>
     </div>
    </p>

    <p class="para">
     <div class="example" id="example-7">
      <p><strong>Ejemplo #7 Intento de vinculación de un objeto a una función anónima estática</strong></p>
      <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$func </span><span style="color: #007700">= static function() {<br />    </span><span style="color: #FF8000">// cuerpo de la función<br /></span><span style="color: #007700">};<br /></span><span style="color: #0000BB">$func </span><span style="color: #007700">= </span><span style="color: #0000BB">$func</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">bindTo</span><span style="color: #007700">(new </span><span style="color: #0000BB">stdClass</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$func</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>
Warning: Cannot bind an instance to a static closure in %s on line %d
</pre></div>
      </div>
     </div>
    </p>
  </div>

  <div class="sect2">
   <h3 class="title">Historial de cambios</h3>
   <p class="para">
    <table class="doctable informaltable">
     
      <thead>
       <tr>
        <th>Versión</th>
        <th>Descripción</th>
       </tr>

      </thead>

      <tbody class="tbody">
       <tr>
        <td>8.3.0</td>
        <td>
         Los closures creados a partir de las <a href="language.oop5.magic.php" class="link">métodos
         mágicos</a> pueden aceptar argumentos nombrados.
        </td>
       </tr>

       <tr>
        <td>7.1.0</td>
        <td>
         Las funciones anónimas no pueden cerrarse sobre <a href="language.variables.predefined.php" class="link">superglobals</a>,
         <var class="varname">$this</var>, o cualquier variable con el mismo nombre que un
         parámetro.
        </td>
       </tr>

      </tbody>
     
    </table>

   </p>
  </div>

  <div class="sect2">
   <h3 class="title">Notas</h3>
   <blockquote class="note"><p><strong class="note">Nota</strong>: 
    <span class="simpara">
     Es posible utilizar las funciones <span class="function"><a href="function.func-num-args.php" class="function">func_num_args()</a></span>,
     <span class="function"><a href="function.func-get-arg.php" class="function">func_get_arg()</a></span> y <span class="function"><a href="function.func-get-args.php" class="function">func_get_args()</a></span>
     en una función anónima.
    </span>
   </p></blockquote>
  </div>
  </div><?php manual_footer($setup); ?>