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

Руководство пользователя PHP

Невозможно использовать $this от анонимной функции до PHP 5.4.0

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

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

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

Изменить: Удалено присвоение символом ref &, поскольку объекты по умолчанию заданы по умолчанию в PHP. $CI = &$this становится $CI = $this

Ответ 1

Это не удастся при попытке вызвать защищенный или закрытый метод на нем, потому что использование этого способа считается вызовом извне. Невозможно обойти это в 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"

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

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"

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

Ответ 2

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

Ответ 3

Не всегда полагайтесь на 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

Ответ 4

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

Ответ 5

Это нормально. Я должен подумать, что вы тоже можете это сделать:

$CI = $this;

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