57

PHP で新しく作成されたオブジェクトにメソッドをチェーンする方法があるかどうかを知りたいですか?

何かのようなもの:

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

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

これを達成する方法を知っている人はいますか?

4

7 に答える 7

104

PHP 5.4+ では、パーサーが変更されたため、次のようなことができます

(new Foo())->xyz();

インスタンス化を括弧で囲み、連鎖させます。

PHP 5.4 より前では、

new Classname();

構文では、インスタンス化からメソッド呼び出しをチェーンすることはできません。これは、PHP 5.3 の構文の制限です。オブジェクトがインスタンス化されると、連鎖することができます。

これを回避するために私が見た 1 つの方法は、ある種の静的インスタンス化方法です。

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

    static public function instantiate()
    {
        return new self();
    }
}


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

new への呼び出しを静的メソッドでラップすることにより、メソッド呼び出しでクラスをインスタンス化でき、それから自由に連鎖できます。

于 2010-02-02T23:57:16.167 に答える
23

次のようにグローバル関数を定義します。

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

その後、次のように呼び出すことができます。

with(new Foo)->xyz();
于 2011-07-12T18:32:15.230 に答える
11

PHP 5.4 では、新しくインスタンス化されたオブジェクトを連鎖させることができます。

http://docs.php.net/manual/en/migration54.new-features.php

古いバージョンの PHP では、Alan Storm のソリューションを使用できます。

于 2012-06-10T16:42:35.710 に答える
6

この回答は古くなっているため、修正したいと考えています。

PHP 5.4.x では、メソッドを new-call にチェーンできます。このクラスを例に取りましょう:

<?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

于 2013-10-26T22:40:18.753 に答える
3

これは古い質問かもしれませんが、プログラミングの多くのことと同様に、最終的には答えが変わります。

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();

うまくいけば、これは誰かが私のように質問に出くわすのに役立ちます!

于 2013-04-30T09:23:57.750 に答える
1

将来のリリースで「これを修正」してくれると本当に助かります。連鎖する機能に本当に感謝しています(特にコレクションを作成する場合):

フレームワークの基本クラスに、連鎖できる 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);

于 2011-02-14T05:43:26.030 に答える