Использование `$this` в анонимной функции в PHP до 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 ответов
Он потерпит неудачу, когда вы попытаетесь вызвать защищенный или закрытый метод для него, потому что использование этого способа считается вызовом извне. Насколько я знаю, в 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 во время выполнения, для функций анонима (повторное закрытие):
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, он не изменяет исходную функцию, а возвращает новую.
Не всегда полагайтесь на то, что PHP передает объекты по ссылке, когда вы сами присваиваете ссылку, поведение не такое, как в большинстве ОО-языков, где изменяется исходный указатель.
ваш пример:
$CI = $this;
$callback = function () use ($CI) {
$CI->public_method();
};
должно быть:
$CI = $this;
$callback = function () use (&$CI) {
$CI->public_method();
};
ЗАМЕЧАНИЕ: ССЫЛКИ "&" и $CI должны быть назначены после того, как будут выполнены последние вызовы, опять же, в противном случае вы можете получить непредсказуемый вывод, в PHP доступ к ссылке не всегда совпадает с доступом к исходному классу - если это имеет смысл.
Это нормальный способ, которым это было сделано.
Кстати, попробуйте удалить &
это должно работать без этого, так как объекты передаются по ссылке любым способом.
Это отлично. Я должен подумать, что вы могли бы сделать это также:
$CI = $this;
... поскольку присваивания, включающие объекты, всегда будут копировать ссылки, а не целые объекты.
Это нормально, если вы передаете по ссылке, это правильный способ сделать это. Если вы используете PHP 5, вам не нужно &
символ перед $this
как это всегда будет проходить по ссылке независимо.