PHPでは、オブジェクトをインスタンス化し、同じ行でメソッドを呼び出すことができますか?


126

私がしたいのは次のようなものです:

$method_result = new Obj()->method();

代わりに:

$obj = new Obj();
$method_result = $obj->method();

私の特定のケースでは、結果は実際には私には関係ありません。しかし、これを行う方法はありますか?


4
ところで、5.4を使用していない場合(おそらく使用していない場合)、オブジェクトをチェーンに返すヘルパー関数を定義できます... function with($ obj){return $ obj; }(laravel:Pからトリックをピックアップしました)..次に、(new Obj)-> method()で実行できます
kapv89

ところで、これを頻繁に行っている場合は、my_method代わりに宣言する必要があるかどうかを検討する価値がありstaticます。
ToolmakerSteve

回答:


166

あなたが要求した機能は、PHP 5.4から利用できます。PHP 5.4の新機能のリストは次のとおりです。

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

そして、新機能リストの関連部分:

インスタンス化時のクラスメンバーアクセスが追加されました(例:(新しいFoo)-> bar())。


9
これは(new Foo)->property、必要に応じて実行できることも意味することに注意してください。
dave1010

1
この方法ではまだプロパティを割り当てることができないことに注意してください。(新しいFoo)-> property = 'property';
CMCDragonkai 2014年

7
@CMCDragonkaiは論理的には理にかなっています。オブジェクトはステートメントの存続期間中のみ存在し(new Foo)->propertyます-オブジェクトはどこにも保存されないため、その後オブジェクトは存在しなくなるため、保存する値はどこにも行きません。
thomasrutter 2015

1
@CMCDragonkai対応するセッターを呼び出すことで、この方法でプロパティを割り当てることができます。必要なことはreturn $this、セッターに追加することだけです。これにより、セッターをチェーンすることもできます。
iloo 2017

質問があります。オブジェクトを再利用できること以外に、別の行でオブジェクトを宣言して変数に保存することには利点がありますか?
タイラースワルツェンブルク2017

37

あなたが求めていることはできません。しかし、PHPではクラスと同じ名前の関数を持つことができるという事実を利用して、「チート」することができます。これらの名前は競合しません。

したがって、次のようなクラスを宣言した場合:

class Test {
    public function __construct($param) {
        $this->_var = $param;
    }
    public function myMethod() {
        return $this->_var * 2;
    }
    protected $_var;
}

次に、そのクラスのインスタンスを返す関数を宣言し、クラスとまったく同じ名前を付けることができます。

function Test($param) {
    return new Test($param);
}

そして今、あなたが尋ねたように、ワンライナーを使用することが可能になります-ただあなたが関数を呼び出しているだけなので、newを使用していません:

$a = Test(10)->myMethod();
var_dump($a);

そしてそれはうまくいきます:ここで、私は得ています:

int 20

出力として。


そして、より良い、あなたはあなたの関数にいくつかのphpdocを置くことができます:

/**
 * @return Test
 */
function Test($param) {
    return new Test($param);
}

このようにすると、IDEにヒントが表示されます-少なくとも、Eclipse PDT 2.xでは。スクリーンショットを見る:



2010-11-30を編集:参考までに、新しいRFCが数日前に提出されました。これは、この機能を将来のバージョンのPHPの1つに追加することを提案しています。

見る : コメントの要求:インスタンスとメソッドの呼び出し/プロパティアクセス

そのため、PHP 5.4または将来の別のバージョンでは、おそらくこれらのようなことを行うことができます。

(new foo())->bar()
(new $foo())->bar
(new $bar->y)->x
(new foo)[0]

19

識別関数を定義することで、より普遍的に行うことができます。

function identity($x) {
    return $x;
}

identity(new Obj)->method();

そうすれば、クラスごとに関数を定義する必要がなくなります。


10
この制限の愚かさを強調するための素晴らしい解決策:)
Ole

19

どうですか:

$obj = new Obj(); $method_result = $obj->method(); // ?

:P


16

いいえ、できません。
インスタンスのメソッドを呼び出す前に、インスタンスを変数に割り当てる必要があります。

あなたが本当にこれをしたくないなら、ropstahが示唆するようにあなたは工場を使うことができます:

class ObjFactory{
  public static function newObj(){
      return new Obj();
  }
}
ObjFactory::newObj()->method();

4
ピムの答えは正しいです。あるいは、オブジェクトのインスタンスを作成したくない場合は、静的関数を使用することができます
マーク

これを使用すると、のpublic static function代わりに使用することが強制されますpublic function。静的を使用することをお勧めしますか?
ichimaru

6

静的なファクトリメソッドを使用してオブジェクトを生成できます。

ObjectFactory::NewObj()->method();

3
別の工場は必要ありません。同じクラスの静的メソッドは同じことを行います。
ブリリアント

3

私も、日付をある形式から別の形式に変換するための単一の式の一部としてこれを達成するためのワンライナーを探していました。これは単一の論理演算なので、1行のコードでこれを行うのが好きです。したがって、これは少し不可解ですが、1行で日付オブジェクトをインスタンス化して使用できます。

$newDateString = ($d = new DateTime('2011-08-30') ? $d->format('F d, Y') : '');

ある形式から別の形式への日付文字列の変換を1行に変換するもう1つの方法は、ヘルパー関数を使用してコードのオブジェクト指向部分を管理することです。

function convertDate($oldDateString,$newDateFormatString) {
    $d = new DateTime($oldDateString);
    return $d->format($newDateFormatString);
}

$myNewDate = convertDate($myOldDate,'F d, Y');

オブジェクト指向のアプローチはクールで必要だと思いますが、面倒で、単純な操作を実行するために多くの手順を必要とする場合があります。


0

質問が進むにつれてこれはかなり古いと思いますが、ここに私が言及すべきと思うものがあります:

「__call()」という特別なクラスメソッドを使用して、クラス内に新しい項目を作成できます。次のように使用します。

<?php
class test
{

function __call($func,$args)
{
    echo "I am here - $func\n";
}

}

    $a = new test();
    $a->new( "My new class" );
?>

出力は次のようになります。

I am here - new

したがって、PHPをだまして、最上位クラス(または実際には任意のクラス)内に「新しい」コマンドを作成し、includeコマンドを__call()関数に配置して、要求したクラスを含めることができます。もちろん、あなたはおそらく$ funcをテストして、それが__call()コマンドに送信された「新しい」コマンドであることを確認したいと思うでしょう。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.