Я хотел бы узнать, есть ли способ цепных методов для вновь созданного объекта в PHP?
Что-то вроде:
class Foo {
public function xyz() { ... return $this; }
}
$my_foo = new Foo()->xyz();
Кто-нибудь знает, как это достичь?
Я хотел бы узнать, есть ли способ цепных методов для вновь созданного объекта в 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 - объединить Alan Storm Foo::instantiate()
factory и метод глобальной функции Kenaniah with()
.
Просто сделайте метод factory глобальной функцией с тем же именем, что и класс!.; -o (добавьте его как удобную обертку вокруг нужного статического Foo::instantiate()
или просто переместите ее там, пока никто не смотрит.)
class Foo
{
public function xyz()
{
echo "Called","\n";
return $this;
}
}
function Foo()
{
return new Foo();
}
$a = Foo()->xyz();
Примечание: