Я принял решение использовать блокировки для своих обратных вызовов вместо create_function
и как таковые поддерживать PHP > 5.3 в основном из-за повышенной отладки, а также потому, что я предположил (что это такое, что говорят о допущении?), что накладные расходы "на лету" компиляции create_function
в моей ситуации, вероятно, компенсировали бы любые дополнительные сравнения и такие, которые должны были быть сделаны внутри функции.
Это может быть и так (для моего приложения), и требуется дополнительное тестирование, но меня заинтересовал вывод этого (очень) простого теста, который показывает, что метод create_function
более чем в два раза быстрее, чем закрытие, когда он может удалить только четыре условных выражения (и concats). Очевидно, что в моем тестовом случае нет дополнительной обработки, и именно там большая часть скорости будет получена или потеряна, но в случае, когда у вас мало дополнительной обработки, но есть много условных выражений (которые можно удалить) и callback называется достаточно раза, я начал думать, что лучше использовать create_function
.
Однако с очевидным сходством между create_function
и eval
я опасаюсь этого.
Итак, главный вопрос в том, каковы различия между анонимными функциями, созданными с помощью create_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();