Действительно ли возможно моделировать закрытия в PHP 5.2.x не использующий globals?

Действительно ли возможно моделировать закрытия в PHP 5.2.x не использующий globals? Я мог думать о пути, который передаст желаемые переменные как дополнительные параметры к закрытию, но это просто не чувствует себя подобно лучшей практике.

Какие-либо идеи?

9
задан aefxx 5 February 2010 в 08:12
поделиться

3 ответа

Интересный вопрос. Я бы сказал вообще невозможно, но давайте посмотрим

Цитирование IBM - Что нового в PHP5.3, часть 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 вы не привязываете, а импортируете, когда создаваемая функция выполняется, то хотелось бы возразить , что это ограничение делает закрытие лямбдой.


EDIT: Хотя решение, предложенное Онно Марсманом ниже, довольно приличное. Оно не полностью имитирует Closures, но реализация довольно близка.

7
ответ дан 2 November 2019 в 23:07
поделиться

Ты имеешь в виду Карри, как http://en.wikipedia.org/wiki/Currying

Затем http://zaemis.blogspot.com/2009/06/currying-in-php.html

Если нет, то неважно. :-)

2
ответ дан 2 November 2019 в 23:07
поделиться

Мое решение: http://techblog.triptic.nl/simulating-closures-in-php-versions-prior-to-php-5-3/

Однако он передает переменные внутри объекта в закрытие в качестве первого аргумента.

3
ответ дан 2 November 2019 в 23:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: