Использование $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;
... поскольку назначения, связанные с объектами, всегда будут копировать ссылки, а не целые объекты.