Я пытаюсь настроить некоторые PHP-методы, которые можно вызывать в инстанцированных и статических контекстах. Каковы хорошие способы сделать это? Например, я хочу иметь возможность:
Foo::bar($item); foo($item)->bar();
Я мог бы настроить два отдельных класса, и каждая функция изменяет thisArg и делегирует их другому, но похоже, что это лучший способ. Единственный способ, которым я мог бы это сделать, только с одним классом, был бы примерно так:
function foo($item = null) { return $item instanceof Foo ? $item : new Foo($item); } class Foo { protected $wrapped; public function __construct($item = null) { $this->wrapped = $item; } public function get() { return $this->wrapped; } public function bar($item = null) { isset($this) and $item = &$this->wrapped; // do stuff with $item return isset($this) ? $this : $item; } }
Если вы посмотрите на код underscore.php, они сделают что-то подобное. Некоторое время назад я прочитал некоторые связанные вопросы, которые указывают, что использование isset($this)
для определения контекста может вызвать предупреждение, но, похоже, оно работает нормально … любые обновленные мысли по этому поводу? Другой возможностью может быть создание двух классов: одного со всеми статическими версиями методов, а затем второго класса, который использует __call для делегирования статическому методу, например:
class _Foo { protected $wrapped; public function __construct($item = null) { $this->wrapped = $item; } public function __call($method_name, $args) { array_unshift($args, $this->wrapped); $this->wrapped = call_user_func_array('Foo::' . $method_name, $args); return $this; } }
Идеи?