Я пытаюсь установить некоторые PHP-методы, которые могут быть вызваны в инстанцированных и статических контекстах. Каковы хорошие способы сделать это? Например, я хочу, чтобы быть в состоянии сделать: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 они делают что-то подобное. Я прочитал некоторые связанные questions from a while back, которые указывают, что использование 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;
}
}
идей?
Именно поэтому я спрашиваю. – ryanve
черт его, но маскировка! Что делать, если я хочу, чтобы класс базы данных назывался статическим одноэлементным в целом, но с возможностью создания экземпляра в случае, если мне нужны 2 соединения? –
@Cory, но '__call'" срабатывает только при вызове недоступных методов в контексте объекта. " Но статические методы ** ** доступны в контексте объекта, поэтому я не думаю, что он срабатывал бы, если метод не существовал. Мне нравится идея. – ryanve