В руководстве по PHP
Невозможно использовать
$this
от анонимной функции до PHP 5.4.0
на странице анонимных функций . Но я обнаружил, что могу заставить его работать, назначив $ this ссылке и передав ссылку на инструкцию use
в определении функции.
$CI = $this; $callback = function () use ($CI) { $CI->public_method(); };
Является ли это хорошей практикой, и есть ли лучший способ доступа к $ this внутри анонимной функции с помощью PHP 5.3?
Изменить: Удалено присвоение символом ref &
поскольку объекты по умолчанию назначаются ref в PHP. $CI = &$this
становится $CI = $this
Это не удастся, если вы попытаетесь вызвать на нем защищенный или закрытый метод, потому что использование этого способа считается вызовом извне. Насколько я знаю, нет способа обойти это в 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 () , где первый параметр может быть использован для указания того, на что указывает это значение, а второй параметр определяет, какой должен быть уровень видимости . Если вы опустите второй параметр, видимость будет похожа на вызов со стороны «снаружи», например. доступ к только общедоступным свойствам. Также обратите внимание на то, как работает bindTo, он не изменяет исходную функцию, а возвращает новую .
Это нормальный способ, которым это было сделано.
btw, попробуйте удалить &
он должен работать без этого, поскольку объекты проходят по ref любым способом.
Не всегда полагайтесь на PHP, чтобы передавать объекты по ссылке, когда вы назначаете ссылку, поведение не такое же, как на большинстве языков OO, где исходный указатель изменен.
ваш пример:
$CI = $this; $callback = function () use ($CI) { $CI->public_method(); };
должно быть:
$CI = $this; $callback = function () use (&$CI) { $CI->public_method(); };
ПРИМЕЧАНИЕ. ССЫЛКА «&» и «$ CI» должны быть назначены после того, как окончательные вызовы были выполнены, опять же, если у вас может быть непредсказуемый вывод, в PHP доступ к ссылке не всегда совпадает с доступом к исходному классу – если это имеет смысл.
Это похоже на то, что если вы пройдете по ссылке, это правильный способ сделать это. Если вы используете PHP 5, вам не нужен символ &
до $this
поскольку он всегда будет проходить по ссылке независимо.
Это отлично. Я должен подумать, что вы тоже можете это сделать:
$CI = $this;
… поскольку назначения с объектами всегда будут копировать ссылки, а не целые объекты.