2012-01-10 22 views
1

;)メソッドチェーン

私の問題がある - ことができますチェーンのメソッドが最後のものかどうか調べる方法はありますか?ほとんどの場合、チェーンの終わりを知り、それに対応する結果を返すために、何らかの最終的なメソッド(実行、送信、..)を使用しています。しかし、チェーン内のすべてのメソッドをチェックし、次のメソッドがないかどうかを検出するよりも、隠された魔法のメソッドやテクニックがあるのだろうか? 最後のメソッドがなければ、文字列(非常に単純な例)ではうまく動作しますが、配列を返す場合は正しく動作しません。

はここに私の抜粋です:私は__toString方法で結果を変更することができ、私はチェーンの結果を印刷したいときは、見

class Chain { 
    private $strArray; 

    function __call($name, $args) { 
     $this->strArray[] = $args[0]; 
     return $this; 
    } 
    function __toString() { 
     return implode('-', $this->strArray); 
    } 
} 
// example 1 
$c = new Chain(); 
$x = $c->foo('hi')->bar('stack'); // need array('hi', 'stack') 

// example 2 
$c = new Chain(); 
$x = $c->foo('hi')->bar('stack')->foobar('overflow'); // need array('hi', 'stack', 'overflow') 

// example 3 
$c = new Chain(); 
echo $c->foo('hi')->foobar('overflow'); // prints 'hi-overflow' 

// example 4 
$c = new Chain(); 
echo $c->foo('hi')->bar('stack')->foobar('overflow'); // prints 'hi-stack-overflow' 

、しかし、私は(例1を配列する必要がある場合は、 2)?追加の「最終的な」方法を呼ぶことなく達成する方法はありますか?

ありがとうございました。お手数をおかけしますようお願い申し上げます。

編集: @bandiからのフィードバックを受けて、ArrayObjectをこのように拡張しようとしました。

class Chain extends ArrayObject { 
    function __call($name, $args) { 
     $this->append($args[0]); 
     return $this; 
    } 
    function __toString() { 
     return implode('-', $this->getIterator()->getArrayCopy()); 
    } 
} 
// returned ref. to object, works fine in loop or accessing offset 
$obj = new Chain; 
$x = $obj->foo('hi')->bar('stack')->foobar('overflow'); // need array('hi', 'stack', 'overflow') 
foreach ($x as $y) { 
    echo $y, "\n"; 
} 
var_dump($x[0], $x[1], $x[2]); 

// returned String 
$c = new Chain; 
echo $c->foo('hi')->foobar('overflow'); // prints 'hi-overflow' 

それは私が望んで、しかし私は$this->getIterator()->getArrayCopy()一部についてとても良い感じはありませんありません。配列にアクセスする簡単な方法はありますか(内部では["storage":"ArrayObject":private])? ありがとう

答えて

0

メソッド連鎖は関数の戻り値を使用しています。この場合、これはオブジェクトへの参照です。戻り値の使用を予測することは、一般的に不可能です。

呼び出されたメソッドに別の何かをしたいことを伝える必要があります。このために2番目の引数を使用することができます。 2番目の引数が定義されていれば、別の結果を返します。もう1つの選択肢は、クラスが印刷されている場合を除いて配列のように動作するようにクラスを変更することです。

+0

よろしくお願いいたします。一般的に私は変数に代入するときに配列を返すが、まだ文字列にキャストするためのオープンオプションを持っていると思います。 $ thisを返すので、私はクラスプロパティ($ strArray)を取得しませんが、望ましくないクラスへの参照全体が "final"メソッドを実装するように強制します。しかし、本当に簡単なことは、あなたが示唆したように、チェーンの最後のメソッドに2番目の引数TRUEを渡すことでしょう。より多くのアドバイスが来るかどうかがわかります; – lp1051

+0

btw。どのように意味しましたか? "もう一つの選択肢は、クラスが印刷されている以外は配列のように動作するようにクラスを変更することです。"私は理解していないと思っています – lp1051

+0

@ lp1051新しいバージョンのphpのクラスシステムには完全に精通していないので、可能かどうかわかりません:クラスを 'array'クラスから派生させて2つのカスタムメソッドを追加します。 – bandi

関連する問題