I had made a decision to use closures for my callbacks instead of create_function
and as such only support PHP > 5.3 mostly due to the increased debugability and also because I assumed (what is it they say about assumption?) that the overhead of the on-the-fly compilation of the create_function
in my situation would probably offset any extra comparisons and such that had to be made within in the function.
This may well still be the case (for my application) and further testing is required, but I was interested in the output of this (very) simple test, that shows the create_function
method being more than twice as fast as the closure when it can remove just four conditionals (and concats). Obviously there is no extra processing going on in my test case, and that is where most of the speed will be gained or lost, but in the case where you have little extra processing but a lot of conditionals (that could be removed) and the callback is called enough times I started to think that it may be better to use create_function
.
However with the obvious similarity between create_function
and eval
, I'm wary of it.
So the main question is what are the differences between anonymous functions created with create_function
and those of closures?
A few specific questions I'm thinking of are, will create_function
even work when eval
functionality is disabled? And, I'm sure I read somewhere recently that create_function
functions will pollute the global (or class) namespace even if declared as inner functions, but closures won't. I can't find the reference to this now, but are either or both of those statements true?
This is the little test I ran:
<?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();