PHP中的闭包或create_function

时间:2011-06-26 16:56:24

标签: php callback closures anonymous-function

我决定使用闭包代替create_function而不是create_function,因此只支持PHP> 5.3主要是由于增加了可调试性,也因为我假设(他们对假设有什么看法?)在我的情况下create_function的动态编译的开销可能会抵消任何额外的比较和必须在函数内部进行。

情况可能仍然如此(对于我的应用程序而言)并且需要进一步测试,但我对此(非常)简单测试的输出感兴趣,该测试显示create_function方法超过两倍当它只能删除四个条件(和concats)时关闭速度很快。显然,在我的测试用例中没有进行额外的处理,这就是大部分速度将获得或丢失的地方,但是在你没有多少额外处理但是有很多条件(可以删除)和回调被召唤的次数我开始认为使用create_function可能更好。

然而,由于evalcreate_function之间存在明显的相似性,我对此持谨慎态度。

所以主要的问题是用create_function创建的匿名函数和闭包函数之间有什么区别?

我正在考虑的一些具体问题是eval即使在create_function功能被禁用时也能正常工作?而且,我确信我最近在某处读到<?php function foo($a=true, $b=true, $c=true, $d=true) { $inner1 = create_function( '', '$r = \''.($a ? 'a' : ''). ($b ? 'b' : ''). ($c ? 'c' : ''). ($d ? 'd' : '').'\'; return $r;' ); $inner2 = function() use ($a, $b, $c, $d) { $r = ''; if($a) { $r .= 'a'; } if($b) { $r .= 'b'; } if($c) { $r .= 'c'; } if($d) { $r .= 'd'; }; return $r; }; $time = microtime(true); for ($x=0; $x<99999; ++$x) { $i1out = $inner1(); } echo '1:'.(microtime(true)-$time).'<br>'; $time = microtime(true); for ($x=0; $x<99999; ++$x) { $i2out = $inner2(); } echo '2:'.(microtime(true)-$time).'<br>'; echo var_dump($i1out===$i2out).'<br>'; } foo(); 函数会污染全局(或类)命名空间,即使声明为内部函数,但闭包不会。我现在找不到对此的引用,但这些语句中的一个或两个都是真的吗?


这是我跑的小测试:

{{1}}

2 个答案:

答案 0 :(得分:6)

构造function() {..}是一个匿名函数,此功能通常与closures一起实现。 create_function和匿名函数都不会污染全局命名空间。

由于匿名函数可以访问周围的变量(闭包部分),理论上它们可能会稍慢。另一方面,如果你正在使用字节码缓存(如果你不是,你显然不关心性能),我会期望匿名函数的“编译”开销稍慢。

但是,匿名函数和create_function之间的差异极不可能是性能问题的根源。因此,如果你很幸运拥有一个带有php&gt; 5.3的目标平台,我会选择一个更具可读性的匿名函数。

答案 1 :(得分:2)

create_function创建一个全局函数,该函数将持续用于程序的其余部分。 create_function只返回函数名称(字符串),因此无法知道您是否仍然可以访问以某种方式存储在某处的名称。因此,即使您无法再访问该名称,也无法进行“垃圾回收”。

这意味着一个大问题是如果你使用create_function创建了很多函数,它将导致你的程序内存不足:

for ($i = 0; $i < 1000000; $i++) {
  $f = create_function('', '');
  // do stuff

  // don't use $f anywhere after this point
}

而使用匿名函数,则不会发生(闭包将被垃圾收集)。