Интересный вопрос. Я бы сказал, это вообще невозможно , но давайте посмотрим
Цитирование IBM - Что нового в PHP5.3, часть 2
Замыкание - это функция, которая оценивается в ее собственной среде, которая имеет одну или несколько связанных переменных, к которым можно обращаться при вызове функции.
и далее (выделено мое)
Переменные, которые должны быть импортированы из внешней среды, указаны в разделе использования определения функции замыкания. По умолчанию они передаются по значению , что означает, что если мы обновим значение, переданное в определении функции замыкания, оно не будет обновлять внешнее значение.
Использование 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
, а импортируете при выполнении созданной функции, я бы хотел возразить , что это ограничение делает закрытие лямбда .
РЕДАКТИРОВАТЬ: Решение, предложенное Onno Marsman ниже довольно прилично, хотя. Он не полностью имитирует замыкания, но реализация довольно близка.