有趣的问题。我会说根本不可能,但让我们看看
引用IBM - What's new in PHP5.3, Part 2
闭包是在自己的环境中计算的函数,它有一个或多个绑定变量,在调用函数时可以访问这些变量。
以及进一步(强调我的)
要从外部环境导入的变量在闭包函数定义的 use 子句中指定。默认情况下,它们按值传递,这意味着如果我们更新闭包函数定义中传递的值,它不会更新外部值。
使用global 将通过引用传递,尽管可以通过在use 子句中使用& 将变量通过引用与闭包绑定,但它已经偏离了5.3 的默认行为。
$var = 'yes';
$fn = create_function('', 'global $var; $var = "no";');
$fn();
echo $var; // outputs no
您可以复制全局变量以便按值使用它,例如
$var = 'yes';
$fn = create_function('', 'global $var; $tmp = $var; $tmp = "no";');
$fn();
echo $var; // outputs yes
另外,全局变量的值(使用create_function时)不会在函数创建时而是在函数运行时计算(绑定)
$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
同样重要的是
当在对象中定义时,一件方便的事情是闭包可以通过 $this 变量完全访问对象,而无需显式导入它。 *虽然我认为这在最终的 PHP5.3 中被删除了
使用global 关键字是不可能的,你也不能只使用$this。使用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();
会导致
Fatal error: Using $this when not in object context
总结一下
虽然您可以创建一个从全局范围导入变量的函数,但您不能使用来自另一个范围的变量来创建一个函数。而且由于在使用 create_function 时您在技术上没有绑定,而是在执行创建的函数时导入,我想争辩说这种限制使闭包成为 lambda。
编辑:下面 Onno Marsman 提供的解决方案相当不错。它没有完全模拟闭包,但实现非常接近。