Объекты и замыкания PHP
В последнее время я задавал несколько вопросов по этой теме, поэтому считаю целесообразным связать соответствующие вопросы.
Замыкания PHP и неявная область действия глобальной переменной
У меня есть набор классов, которые используют замыкания, как в примере ниже (имейте в виду, что я быстро собрал этот пример для этого потока), Мой вопрос заключается в передаче аргумента $obj
функциям.
Существует ли какая-либо волшебная переменная (кашель-$this
-кашель), который позволил бы мне получить доступ к объекту, из которого он вызывается, вместо того, чтобы объявлять аргумент-заполнитель $obj
или что-то еще? Возможно, я неправильно понял, но, похоже, функциональность, которую я ищу, была удалена, по крайней мере, в контексте $this
.
class Test{
private $_color;
protected $_children = array();
public function __construct(Closure $function){
$function($this);
}
public function create(Closure $function){
return new self($function);
}
public function color($color){
$this->_color = $color;
return $this;
}
public function add(Closure $function){
$this->_children[] = new Test($function);
return $this;
}
}
Test::create(function($obj){
$obj->color('Red')
->add(function(){
$obj->color('Green');
})
->color('Blue');
});
Единственная альтернатива, которую я могу видеть сразу, - это сохранение экземпляра каждого объекта при создании и предоставление функции для возврата этого экземпляра следующим образом:
class Test{
private $_color;
private static $_instance;
protected $_children = array();
public function __construct(Closure $function){
self::$_instance = $this;
$function();
}
.
.
.
public static function this(){
return self::$_instance;
}
}
Test::create(function(){
Test::this()
->color('Red')
->add(function(){
Test::this()
->color('Green');
})
->color('Blue');
});
1 answers
Вам следует использовать первую версию. Предоставление экземпляра класса статически не очень хорошо (кроме использования одного элемента). Представьте, что у вас есть два экземпляра. Тогда только последнее будет статически обслуживаться. Вы ничего не смогли бы сделать с первым.
Тем не менее, даже при вашем первом подходе существует немаловажное ограничение: вы можете получить доступ только к общедоступным методам. Существует хитрый обходной путь, использующий отражение вокруг этого. Итак, вы используете только публичные методы?
В один точка Closure
считалась деталью реализации и на нее нельзя было полагаться. Это больше не так; Closure
- документированный тип анонимных функций.