Funciones anónimas
  
   Las funciones anónimas, también llamadas closures o closures
   permiten la creación de funciones sin especificar su nombre.
   Son particularmente útiles como funciones de devolución de llamada callable,
   pero su utilización no se limita a este único uso.
  
  
   Las funciones anónimas están implementadas utilizando la clase
   Closure.
  
  
   Ejemplo #1 Ejemplos con funciones anónimas
   
<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
    return strtoupper($match[1]);
}, 'hola-mundo');
?>
    
   
  
   Las funciones anónimas también pueden ser utilizadas como valores de
   variables. PHP convertirá automáticamente estas expresiones
   en objetos Closure. Asignar un closure
   a una variable es lo mismo que una asignación clásica,
   incluyendo el punto y coma final.
  
  
   Ejemplo #2 Asignación de función anónima a una variable
   
<?php
$saludo = function($name) {
    printf("Hola %s\r\n", $name);
};
$saludo('Mundo');
$saludo('PHP');
?>
    
   
  
   Las funciones anónimas pueden heredar variables del contexto de su
   padre. Estas variables deben entonces ser pasadas en la construcción
   de lenguaje use.
   A partir de PHP 7.1, estas variables no deben incluir superglobals,
   $this, o variables con el mismo nombre que un
   parámetro. Una declaración de tipo de retorno para la función debe ser colocada
   después de la cláusula use.
  
  
   Ejemplo #3 Herencia de variable desde el contexto padre
   
<?php
$message = 'hola';
// Sin "use"
$example = function () {
    var_dump($message);
};
$example();
// Hereda $message
$example = function () use ($message) {
    var_dump($message);
};
$example();
// El valor de la variable heredada es definido cuando la función es
// definida no cuando es llamada
$message = 'mundo';
$example();
// Reinicialización de la variable message
$message = 'hola';
// Herencia por referencia
$example = function () use (&$message) {
    var_dump($message);
};
$example();
// El cambio de valor en el contexto padre es reflejado al
// llamar a la función.
$message = 'mundo';
$example();
// Las funciones anónimas también aceptan argumentos clásicos
$example = function ($arg) use ($message) {
    var_dump($arg . ' ' . $message);
};
$example("hola");
// Declaración de tipo de retorno viene después de la cláusula use
$example = function () use ($message): string {
    return "hola $message";
};
var_dump($example());
?>
    
   Resultado del ejemplo anterior es similar a:
Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hola"
string(5) "hola"
string(5) "hola"
string(5) "mundo"
string(11) "hola mundo"
string(11) "hola mundo"
 
   
  
   A partir de PHP 8.0.0, la lista de variables heredadas del contexto puede
   incluir una coma final, que será ignorada.
  
  
   La herencia del contexto padre
   no es 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:
  
  
   Ejemplo #4 Funciones anónimas y contexto
   
<?php
// Un carrito de compra simple, que contiene una lista de productos
// seleccionados y la cantidad deseada de cada producto. Incluye
// un método que calcula el precio total de los elementos en el carrito
// utilizando una función de devolución de llamada anónima.
class Carrito
{
    const PRECIO_MANTEQUILLA  = 1.00;
    const PRECIO_LECHE    = 3.00;
    const PRECIO_HUEVO    = 6.95;
    protected $products = array();
    public function add($product, $quantity)
    {
        $this->products[$product] = $quantity;
    }
    public function getQuantity($product)
    {
        return isset($this->products[$product]) ? $this->products[$product] :
               FALSE;
    }
    public function getTotal($tax)
    {
        $total = 0.00;
        $callback =
            function ($quantity, $product) use ($tax, &$total)
            {
                $pricePerItem = constant(__CLASS__ . "::PRECIO_" .
                    strtoupper($product));
                $total += ($pricePerItem * $quantity) * ($tax + 1.0);
            };
        array_walk($this->products, $callback);
        return round($total, 2);
    }
}
$mi_carrito = new Carrito;
// Añadir elementos al carrito
$mi_carrito->add('mantequilla', 1);
$mi_carrito->add('leche', 3);
$mi_carrito->add('huevo', 6);
// Mostrar el precio con 5.5% de IVA
print $mi_carrito->getTotal(0.055) . "\n";
// El resultado será 54.29
?>
    
   
  
   Ejemplo #5 Vinculación automática de $this
   
<?php
class Test
{
    public function testing()
    {
        return function() {
            var_dump($this);
        };
    }
}
$object = new Test;
$function = $object->testing();
$function();
?>
    
   El ejemplo anterior mostrará:
 
  
   Cuando se declara en el contexto de una clase, la clase
   actual es automáticamente vinculada, haciéndola $this
   disponible en el contexto de la función. Si este vínculo automático de
   la clase actual no es deseado, entonces las
   funciones anónimas
    estáticas pueden ser utilizadas en su lugar.
  
  
   Las funciones anónimas estáticas
   
    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.
   
   
    
     Ejemplo #6 Intento de uso de $this en una función anónima estática
     
<?php
class Foo
{
    function __construct()
    {
        $func = static function() {
            var_dump($this);
        };
        $func();
    }
};
new Foo();
?>
       
      El ejemplo anterior mostrará:
Notice: Undefined variable: this in %s on line %d
NULL
 
      
    
    
     
      Ejemplo #7 Intento de vinculación de un objeto a una función anónima estática
      
<?php
$func = static function() {
    // cuerpo de la función
};
$func = $func->bindTo(new stdClass);
$func();
?>
       
      El ejemplo anterior mostrará:
Warning: Cannot bind an instance to a static closure in %s on line %d