Я хотел бы знать, есть ли способ связать методы на вновь созданном объекте в PHP?
Что-то вроде:
class Foo { public function xyz() { ... return $this; } } $my_foo = new Foo()->xyz();
Кто-нибудь знает, как это достичь?
В PHP 5.4+ анализатор был изменен, поэтому вы можете сделать что-то вроде этого
(new Foo())->xyz();
Оберните экземпляр в скобках и отцепите.
До PHP 5.4, когда вы используете
new Classname();
синтаксис, вы не можете связать вызов метода с экземпляром. Это ограничение синтаксиса PHP 5.3. Как только объект создается, вы можете цепляться.
Один из методов, который я видел, чтобы обойти это, – это статический метод создания экземпляров.
class Foo { public function xyz() { echo "Called","\n"; return $this; } static public function instantiate() { return new self(); } } $a = Foo::instantiate()->xyz();
Обернув вызов new в статическом методе, вы можете создать экземпляр класса с вызовом метода, и тогда вы сможете его отключить.
Определите глобальную функцию следующим образом:
function with($object){ return $object; }
Затем вы сможете позвонить:
with(new Foo)->xyz();
В PHP 5.4 вы можете связать недавно созданный объект:
http://docs.php.net/manual/en/migration54.new-features.php
Для более старых версий PHP вы можете использовать решение Alan Storm.
Этот ответ устарел – поэтому вы хотите его исправить.
В PHP 5.4.x вы можете связать метод с новым вызовом. Давайте возьмем этот класс в качестве примера:
<?php class a { public function __construct() { echo "Constructed\n"; } public function foo() { echo "Foobar'd!\n"; } }
Теперь мы можем использовать это: $b = (new a())->foo();
И выход:
Constructed Foobar'd!
Дополнительную информацию можно найти в руководстве: http://www.php.net/manual/en/migration54.new-features.php
Ну, это может быть старый вопрос, но, как и во многих вещах в программировании, – в конце концов, ответ меняется.
Что касается PHP 5.3, нет, вы не можете напрямую связать его с конструктором. Однако, чтобы расширить принятый ответ, чтобы правильно разместить для наследования, вы можете:
abstract class Foo { public static function create() { return new static; } } class Bar extends Foo { public function chain1() { return $this; } public function chain2() { return $this; } } $bar = Bar::create()->chain1()->chain2();
Это будет отлично работать и вернет вам новый экземпляр Bar ().
Однако в PHP 5.4 вы можете просто:
$bar = (new Bar)->chain1()->chain2();
Надеюсь, это поможет кому-то споткнуться по вопросу, как у меня!
Было бы очень полезно, если бы они исправили это в будущей версии. Я действительно ценю способность к цепочке (особенно при заполнении коллекций):
Я добавил метод к базовому классу моей структуры под названием create (), который можно связать с. Должно работать со всеми классами потомков автоматически.
class baseClass { ... public final static function create() { $class = new \ReflectionClass(get_called_class()); return $class->newInstance(func_get_args()); } ... public function __call($method, $args) { $matches = array(); if (preg_match('/^(?:Add|Set)(?<prop>.+)/', $method, $matches) > 0) { // Magic chaining method if (property_exists($this, $matches['prop']) && count($args) > 0) { $this->$matches['prop'] = $args[0]; return $this; } } } ... }
Класс :: Create () -> SetName ( 'Kris') -> SetAge (36);
Просто ради полноты (и для удовольствия …), так как никто, кажется, не упомянул решение с самым коротким (и наименее сложным) кодом.
Для часто используемых короткоживущих объектов, особенно при написании тестовых примеров, где вы обычно делаете много создания объектов, вы можете оптимизировать для удобства ввода (а не чистоты), а sorta – объединить фабрику Foo::instantiate()
Alan Storm метод и метод Kenaniah with()
глобальной функцией.
Просто сделайте фабричный метод глобальной функцией с тем же именем, что и класс! , ; -o (либо добавить его как удобную обертку вокруг правильного статического Foo::instantiate()
или просто переместить его там, пока никто не смотрит.)
class Foo { public function xyz() { echo "Called","\n"; return $this; } } function Foo() { return new Foo(); } $a = Foo()->xyz();
ЗАМЕТКА: