Объекты и замыкания 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');
    });
Author: Community, 2010-10-31

1 answers

Вам следует использовать первую версию. Предоставление экземпляра класса статически не очень хорошо (кроме использования одного элемента). Представьте, что у вас есть два экземпляра. Тогда только последнее будет статически обслуживаться. Вы ничего не смогли бы сделать с первым.

Тем не менее, даже при вашем первом подходе существует немаловажное ограничение: вы можете получить доступ только к общедоступным методам. Существует хитрый обходной путь, использующий отражение вокруг этого. Итак, вы используете только публичные методы?

В один точка Closure считалась деталью реализации и на нее нельзя было полагаться. Это больше не так; Closure - документированный тип анонимных функций.

 1
Author: NikiC, 2012-02-13 13:17:03