Как цепочка метод на вновь созданный объект?


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

что-то типа:

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

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

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

7 52

7 ответов:

в 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 вы можете использовать решение Алана шторма.

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

в PHP 5.4.х вы можете привязать метод к новому вызову. Давайте возьмем этот класс в качестве примера:

<?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;
            }
        }
    }
    ...
}

Class:: create () - >SetName ('Kris') - >SetAge (36);

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

для часто используемых недолговечных объектов, особенно при написании тестовых случаев, где вы обычно делаете много создания объектов, вы можете оптимизировать для удобства ввода (а не чистоты), и sorta ' combine Alan Storm's Foo::instantiate() метод фабрики и Хенания это with() глобальная функция метод.

просто сделайте заводской метод a глобальная функция С тем же именем, что и класс!. ;- o (либо добавьте его в качестве удобной обертки вокруг правильного статического Foo::instantiate() или просто переместить его туда, пока никто не смотрит.)

class Foo
{
    public function xyz()
    {
        echo "Called","\n";
        return $this;
    }
}

function Foo()
{
    return new Foo();
}

$a = Foo()->xyz();

Примечание:

  • я бы не сделал этого на производственном коде. В то время как kinda 'sexy, это злоупотребление основными принципами кодирования (например," принцип наименьшего удивления " (хотя это на самом деле довольно интуитивный синтаксис), или "не повторяйте себя", esp. если обернуть реальный заводской метод с некоторыми параметрами, что само по себе, кстати, уже является злоупотреблением сухим...), плюс PHP может измениться в будущем, чтобы сломать такой код забавными способами.