Interesante pregunta. Yo diría que que no es posible en absoluto, pero vamos a ver
Citando IBM - What's new in PHP5.3, Part 2
Un cierre es una función que se evalúa en su propio entorno, que tiene una o más variables encuadernadas que pueden ser accedido cuando se llama a la función.
y además (énfasis mío)
Variables a ser importado del ambiente exterior se especifican en la cláusula de uso de la definición de la función de cierre. Por defecto, se pasan por el valor, lo que significa que si actualizamos el valor pasado dentro de la definición de la función de cierre, no se actualizará el valor exterior.
Usando global
pasaría por referencia y aunque es posible enlazar las variables por referencia con un cierre mediante el uso de &
en la cláusula use
, ya es una desviación del comportamiento 5,3 predeterminada.
$var = 'yes';
$fn = create_function('', 'global $var; $var = "no";');
$fn();
echo $var; // outputs no
Puede copiar la variable global para usarla como valor, por ej.
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; $tmp = "no";');
$fn();
echo $var; // outputs yes
Además, el valor de la variable global (cuando se utiliza create_function
) no será evaluado (ligado) cuando se crea la función, pero cuando la función se ejecuta
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; return $tmp;');
$var = 'maybe';
echo $fn(); // outputs maybe
$var = 'yes';
$fn = function() use ($var) { return $var; };
$var = 'maybe';
echo $fn(); // outputs yes
También es importante
Cuando se define dentro de un objeto, una cosa útil es que el cierre tiene acceso completo al objeto a través de $ this variable, sin la necesidad de importarlo explícitamente. * Aunque creo que esto se abandonó en PHP5.3 última
Esto es imposible con la palabra clave global
y que tampoco puede simplemente usar $this
. No hay forma de hacer referencia a una propiedad de una clase al definir el cuerpo de la función con create_function
.
class A {
protected $prop = 'it works';
public function test()
{
$fn = create_function('', 'echo $this->prop;');
return $fn;
}
}
$a = new A;
$fn = $a->test();
$fn();
dará lugar a
Fatal error: Using $this when not in object context
Para resumir esto
Si bien se puede crear una función de importación de una variable del ámbito mundial, no se puede no se puede crear uno usando variables de otro ámbito. Y como técnicamente no es vinculante al usar create_function
, pero importando cuando se ejecuta la función creada, me gustaría argumentar que esta limitación hace que el cierre sea lambda.
EDITAR: La solución ofrecida por Onno Marsman a continuación es bastante decente. No simula completamente Closures, pero la implementación es bastante cercana.
Es realmente triste que PHP no sea compatible con una construcción tan impresionante. – ChaosPandion
@ ChaosPandion pero lo hace desde PHP5.3 hasta – Gordon
, sí, pero tiene que listar las variables cerradas explícitamente. "Cierres con muletas", por así decirlo. Sin embargo, es mejor que nada. – user187291