Использование `$this` в анонимной функции в PHP pre 5.4.0


в руководстве PHP указано

Это не возможно, чтобы использовать $this из анонимной функции перед PHP 5.4.0

на страница анонимные функции. Но я обнаружил, что могу заставить его работать, назначив $this к переменной и передача переменной в use заявление в определении функции.

$CI = $this;
$callback = function () use ($CI) {
    $CI->public_method();
};

это хорошая практика?
Есть ли лучший способ получить доступ $this внутри анонимной функция с использованием PHP 5.3?

5 83

5 ответов:

это не удастся, когда вы попытаетесь вызвать защищенный или закрытый метод на нем, потому что использование его таким образом считается вызовом извне. Насколько я знаю, нет способа обойти это в 5.3, но приходите PHP 5.4, он будет работать так, как ожидалось, из коробки:

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}
$hello = new Hello();
$helloPrinter = $hello->createClosure();
$helloPrinter(); // outputs "Hello world"

более того, вы сможете изменить то, что $this указывает на время выполнения, для функций anonymus (closure rebinding):

class Hello {

    private $message = "Hello world\n";

    public function createClosure() {
        return function() {
            echo $this->message;
        };
    }

}

class Bye {

    private $message = "Bye world\n";

}

$hello = new Hello();
$helloPrinter = $hello->createClosure();

$bye = new Bye();
$byePrinter = $helloPrinter->bindTo($bye, $bye);
$byePrinter(); // outputs "Bye world"

фактически, функции Анонимуса будут иметь bindTo() метод, где первый параметр может использоваться для указания того, на что указывает $this, а второй параметр управляет каким должен быть уровень видимости. Если вы опустите второй параметр, видимость будет похожа на вызов извне, например. доступны только общие свойства. Также обратите внимание на то, как работает bindTo, он не изменяет исходную функцию,он возвращает новый.

это нормальный способ, которым это было сделано.
b. t. w, попробуйте удалить & Он должен работать без этого, так как объекты проходят мимо ref любым способом.

не всегда полагайтесь на PHP для передачи объектов по ссылке, когда вы назначаете саму ссылку, поведение не такое же, как в большинстве языков OO, где исходный указатель изменен.

ваш пример:

$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};

должно быть:

$CI = $this;
$callback = function () use (&$CI) {
$CI->public_method();
};

обратите внимание, что ссылка " & " и $CI должны быть назначены после того, как окончательные вызовы на нем были сделаны, опять же, у вас может быть непредсказуемый вывод, в PHP доступ к ссылке не всегда совпадает с доступом исходный класс-если это имеет смысл.

http://php.net/manual/en/language.references.pass.php

это кажется нормальным, если вы проходите по ссылке, это правильный способ сделать это. Если вы используете PHP 5 вам не нужно & символ $this как это всегда будет проходить по ссылке независимо.

Это нормально. Я думаю, что вы могли бы сделать это:

$CI = $this;

... поскольку назначения с участием объектов всегда будут копировать ссылки, а не целые объекты.