PHP объекты и замыкания - PullRequest
       27

PHP объекты и замыкания

2 голосов
/ 31 октября 2010

Недавно я задавал несколько вопросов по этой теме, поэтому считаю целесообразным связать связанные вопросы.

Закрытия PHP и неявная область действия глобальной переменной

У меня есть набор классов, которые используют замыкания, как в примере ниже (имейте в виду, я быстро собрал этот пример вместе для этого потока) Мой вопрос заключается в передаче аргумента $obj в функции.

Существует ли какая-либо переменная magic ( cough- $this -cough ), которая позволила бы мне получить доступ к объекту, из которого она вызвана, вместо необходимостиобъявить аргумент-заполнитель $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 Ответ

1 голос
/ 31 октября 2010

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

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

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

...