Funciones
PHP Manual

Funciones anónimas

Las funciones anónimas, también conocidas como clausuras (closures), permiten la creación de funciones que no tienen un nombre especificado. Son más útiles como valor de los parámetros de llamadas de retorno, pero tienen muchos otros usos.

Las funciones anónimas están implementadas utilizando la clase Closure.

Ejemplo #1 Ejemplo de función anónima

<?php
echo preg_replace_callback('~-([a-z])~', function ($coincidencia) {
    return 
strtoupper($coincidencia[1]);
}, 
'hola-mundo');
// imprime holaMundo
?>

Las clausuras también se pueden usar como valores de variables; PHP automáticamente convierte tales expresiones en instancias de la clase interna Closure. Se asume que una clausura a una variable usa la misma sintaxis que cualquier otra asignación, incluido el punto y coma final:

Ejemplo #2 Ejemplo de asignación de variable de una función anónima

<?php
$saludo 
= function($nombre)
{
    
printf("Hola %s\r\n"$nombre);
};

$saludo('Mundo');
$saludo('PHP');
?>

Las clausuras también pueden heredar variables del ámbito padre. Cualquier variable de estas debe ser pasado al constructor del lenguaje use.

Ejemplo #3 Heredar variables de un ámbito padre

<?php
$mensaje 
'hola';

// Sin "use"
$ejemplo = function () {
    
var_dump($mensaje);
};
$ejemplo();

// Heredar $mensaje
$ejemplo = function () use ($mensaje) {
    
var_dump($mensaje);
};
$ejemplo();

// El valor de la variable heredada está cuando la función
// está definida, no cuando se le invoca
$mensaje 'mundo';
$ejemplo();

// Reiniciar el mensaje
$mensaje 'hola';

// Heredar por referencia
$ejemplo = function () use (&$mensaje) {
    
var_dump($mensaje);
};
$ejemplo();

// El valor cambiado en el ámbito padre
// se refleja dentro de la llamada a la función
$mensaje 'mundo';
$ejemplo();

// Las clausuras también aceptan argumentos normales
$ejemplo = function ($arg) use ($mensaje) {
    
var_dump($arg ' ' $mensaje);
};
$ejemplo("hola");
?>

El resultado del ejemplo sería algo similar a:

Notice: Undefined variable: message in /example.php on line 6
NULL
string(4) "hola"
string(4) "hola"
string(4) "hola"
string(5) "mundo"
string(10) "hola mundo"

Heredar variables del ámbito padre no es lo mismo que usar variables globales. Las variables globales existen en el ámbito global, lo que implica que no importa qué función se esté ejecutando. El ámbito padre de una clausura es la función en la que la clausura fue declarado (no necesariamente la función desde la que se llamó). Vea el siguiente ejemplo:

Ejemplo #4 Clausuras y ámbito

<?php
// Un carro de compras básico que contiene una lista de productos añadidos
// y la cantidad de cada producto. Incluye un método que
// calcula el precio total de los artículos del carro usando una
// clausura como llamada de retorno.
class Carro
{
    const 
PRECIO_MANTEQUILLA 1.00;
    const 
PRECIO_LECHE       3.00;
    const 
PRECIO_HUEVOS      6.95;

    protected 
$productos = array();

    public function 
añadir($producto$cantidad)
    {
        
$this->productos[$producto] = $cantidad;
    }

    public function 
obtenerCantidad($producto)
    {
        return isset(
$this->productos[$producto]) ? $this->productos[$producto] :
               
FALSE;
    }

    public function 
obtenerTotal($impuesto)
    {
        
$total 0.00;

        
$llamadaDeRetorno =
            function (
$cantidad$producto) use ($impuesto, &$total)
            {
                
$precioUnidad constant(__CLASS__ "::PRECIO_" .
                    
strtoupper($producto));
                
$total += ($precioUnidad $cantidad) * ($impuesto 1.0);
            };

        
array_walk($this->productos$llamadaDeRetorno);
        return 
round($total2);
    }
}

$mi_carro = new Carro;

// Añadir algunos artículos al carro
$mi_carro->añadir('mantequilla'1);
$mi_carro->añadir('leche'3);
$mi_carro->añadir('huevos'6);

// Imprimir el total con un impuesto de venta del 5%.
print $mi_carro->obtenerTotal(0.05) . "\n";
// El resultado es 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 resultado del ejemplo sería:

object(Test)#1 (0) {
}

Salida del ejemplo anterior en PHP 5.3:

Notice: Undefined variable: this in script.php on line 8
NULL

A partir de PHP 5.4.0, cuando se declara en el contexto de una clase, la clase actual está vinculada a ella automáticamente, haciendo que $this esté disponible dentro del ámbito de la función. Si no se desea esta vinculación automática de la clase actual, se deberían usar funcions anónimas estáticas en su lugar.

Static anonymous functions

A partir de PHP 5.4, las funciones anónimas pueden ser declaradas estáticamente. Esto evita tener la clase actual vinculada automáticamente a ellas. Los objetos tampoco podrían vincularse a ellas durante la ejecución.

Ejemplo #6 Intentar usar $this dentro de una función anónima estática

<?php

new class {
    function 
__construct()
    {
        (static function() {
            
var_dump($this);
        })();
    }
};
?>

El resultado del ejemplo sería:

Notice: Undefined variable: this in %s on line %d
NULL

Ejemplo #7 Intentar vincular un objeto a una función anónima estática

<?php

(static function() {
    
// function body
})->call(new StdClass);
?>

El resultado del ejemplo sería:

Warning: Cannot bind an instance to a static closure in /in/sLLS9 on line 5

Historial de cambios

Versión Descripción
5.4.0 Las funciones anónimas pueden usar $this, así como ser declaradas státicamente.
5.3.0 Las funciones anónimas se encuentran disponibles.

Notas

Nota: Es posible usar func_num_args(), func_get_arg(), y func_get_args() desde dentro de una clausura.


Funciones
PHP Manual