0

次の文字列があります。

$str = "methodA()->methodB()->methodC"

そして、オブジェクトの「チェーン」を呼び出したい

$obj->$str

現在 ()-> で分割して 1 つずつ呼び出していますが、もっと良い方法があるはずです。

どうすれば1行で呼び出すことができますか? ありがとう!

編集: いくつかのより多くのコンテキスト情報:

Zend Lucene で検索可能なスキーマから特定のテーブルを作成できるように、symfony 1.4 の Doctrine Behavior を作成しました。

要するに、「検索可能なフィールドを取得するには、methodA()->methodB()->methodC() を呼び出す必要があります」という動作を言う方法が必要です。

EDIT2:多分私は十分に明確ではありませんでした。$obj と $str は実行時に決定されるため、提案の一部は適用されません。

EDIT3:あなたが疑問に思っている場合のために、私は現在これをやっています:

  <?php
  $chain = explode("()->",$str);
  $method = array_shift($chain);
  $value = $obj->$method();
  foreach($chain as $method){
    $value = $value->$method();
  }
4

6 に答える 6

2

主な質問にコメントを書いた後、可能な解決策を考えましたが、少し冗長で手動です (チェーンされたメソッドの数に対して合理的に期待できる数の case ステートメントを作成する必要があります)。

function chain_execute($obj, $str) {
    $chain = explode("->",$str);
    $chain = array_map('trim', $chain);
    $chain_count = count($chain);
    switch($chain_count) {
        case 1:
            return $obj->{$chain[0]}();
            break;
        case 2:
            return $obj->{$chain[0]}()->{$chain[0]}();
            break;
        case 3:
            return $obj->{$chain[0]}()->{$chain[1]}()->{$chain[2]}();
            break;
        // etc.
        default:
            // not a value you were expecting
            throw new Exception('Invalid number of methods chained: ' . $chain_count);
            break;
    }
}

使用法は次のとおりです。

$result = chain_execute($obj, "methodA->methodB->methodC");
于 2012-09-13T14:36:33.537 に答える
0

次は機能しますか?

$str = $methodA()->$methodB()->$methodC();
于 2012-09-12T14:39:00.323 に答える
0

私の答えは、メソッド (methodA、methodB、および methodC) へのアクセス権があり、それらを編集できること、および各メソッドが $obj がインスタンスであるクラスに属していることを前提としています。

クラスのインスタンスを返すように各メソッドを更新します。これは、int、bool、string などのプリミティブ データ型を返さないことを前提として機能します。

<?php
class Example {
    public function methodA() {
        echo "method a\n";
        return $this;
    }
    public function methodB() {
        echo "method b\n";
        return $this;
    }
    public function methodC() {
        echo "method c\n";
        return $this;
    }
}
?>

Example をインスタンス化し、$obj に保存して、メソッドを連続して呼び出します。

<?php
$obj = new Example();
$obj->methodA()->methodB()->methodC();
?>

どちらが出力されますか:

method a
method b
method c
于 2012-09-12T19:09:59.847 に答える
0

私は一般的にevalを使用しないことをお勧めしますが...

eval("$obj->$str;");

ただし、私はあなたのケースを再評価し、おそらく期待どおりに各関数を1つずつ直接呼び出します。

于 2012-09-12T14:29:08.477 に答える
0

あなたの方法はすでに良いですが...試してみてください

$str = "{$obj->methodA()->methodB()->methodC()}";
于 2012-09-12T14:30:11.737 に答える
0

それは邪悪なアプローチです。

ユースケースを提供していただけますか (興味があります)。

call_user_func()を連続して使用できます。そのために、表記を解析してチェーンを呼び出すことができるヘルパー メソッドを記述できます。

于 2012-09-12T14:30:52.930 に答える