Подтвердить что ты не робот

Как связать метод с новым созданным объектом?

Я хотел бы узнать, есть ли способ цепных методов для вновь созданного объекта в PHP?

Что-то вроде:

class Foo {
    public function xyz() { ... return $this; }
}

$my_foo = new Foo()->xyz();

Кто-нибудь знает, как это достичь?

4b9b3361

Ответ 1

В 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 в статическом методе, вы можете создать экземпляр класса с вызовом метода, и тогда вы сможете его отключить.

Ответ 2

Определите глобальную функцию следующим образом:

function with($object){ return $object; }

Затем вы сможете позвонить:

with(new Foo)->xyz();

Ответ 4

Этот ответ устарел - поэтому вы хотите его исправить.

В 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

Ответ 5

Ну, это может быть старый вопрос, но, как и во многих вещах в программировании, - в конце концов, ответ меняется.

Что касается 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();

Надеюсь, это поможет кому-то споткнуться по вопросу, как у меня!

Ответ 6

Было бы очень полезно, если бы они исправили это в будущей версии. Я очень ценю способность к цепочке (особенно при заполнении коллекций):

Я добавил метод к базовому классу моей структуры под названием 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);

Ответ 7

Просто для полноты (и для удовольствия от этого...), поскольку никто, кажется, не упомянул решение с самым коротким (и наименее сложным) кодом.

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

Примечание:

  • Я НЕ ДОЛЖЕН СДЕЛАТЬ ЭТО по производственному коду. Хотя это сексуально, это злоупотребление основными принципами кодирования (например, "принцип наименьшего удивления" (хотя это на самом деле довольно интуитивный синтаксис) или "не повторяйте себя", особенно если обернуть реальный метод factory с некоторыми параметрами, которые сами, BTW, уже злоупотребляют DRY...), плюс PHP может измениться в будущем, чтобы сломать код как это смешными способами.