[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: *RECURSION*
twin
Нарвался тут на неприятность небольшую, может кому пригодится.

Смысл в том, что замыкание, передаваемое аргументом, тащит за собой область видимости. Делает это весьма нетривиальным образом - объекту Closure псевдопеременной $this назначает объект, в котором сформировано замыкание. Это не секрет и не новость. Но тут оказывается есть подвох. По порядку.

Допустим есть контейнер (весьма упрощенно)
class Container
{
protected $stack = [];

public function add($callable)
{
$this->stack[] = $callable;
var_dump($this->stack);
}
}


Если зарядить в него анонимную функцию:

class Example
{
public function __construct($container)
{
$container->add(function (){});
}
}


$ex = new Example(new Container);


все будет тип-топ:
array(1) {
[0]=>
object(Closure)#3 (1) {
["this"]=>
object(Example)#1 (0) {
}
}
}


Однако если этот класс юзает контейнер свойством:
class Example
{
protected $container;

public function __construct($container)
{
$this->container = $container;
$this->container->add(function (){});
}
}


$ex = new Example(new Container);


то наблюдается рекурсивная ссылка:
array(1) {
[0]=>
object(Closure)#3 (1) {
["this"]=>
object(Example)#1 (1) {
["container":protected]=>
object(Container)#2 (1) {
["stack":protected]=>
*RECURSION*
}
}
}
}


Печалька в том, что PHP на это никак не реагирует. Может оно и не критично, но я затестил, поджирает немного и время и память. Но это бы полбеды. Важно другое - это не нормальное поведение, и фиг знает, как может аукнуться.

Бороться можно обявив замыкание статическим, но это не всегда подходит.

Так что имейте ввиду. :)

_____________
Если вам недостаточно собственных заблуждений, можно расширить их мнениями экспертов.

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.