2016-11-29 10 views
3

PHPでメソッドを条件付きで連鎖させるにはどうすればよいですか?たとえば、これは正常に動作します。メソッドを条件付きで連鎖させますか?

$a->foo()->bar->baz->qux(); 

ただし、状況によっては、いくつかの方法を連鎖させたいが、他の方法は連鎖したくない。基本的には、次のコードを短く:次のようなものがうまくいく理想的

if ($cond === true) { 
    $a->foo()->baz(); 
} else { 
    $a->foo()->bar(); 
} 

を:

$a->foo() 
    ->bar() 
    ($cond === true) ? ->baz() : ->qux() 
    ->more(); 

また、どのように我々は条件付きで条件に応じて、方法(またはしない)チェーンのでしょうか?例:あなたが探しているもの

$a->foo() 
    ->bar() 
    if($cond === true) ->baz() 
    ->more(); 
+3

必要がありませんが、そのようなあなたのコードをあいまいにすることを行うことができます方法を示し、以下の自己説明モックスニペット。少年である "見た目のクール"とは別に短い表記には0のメリットがあります。もしあなたが学びたいと思っているなら、それよりもプログラマーを育ててください。 – Weltschmerz

+0

@Weltschmerz私の特別なケースでは、それは見た目のクールな問題ではありませんが、私は単にこのようなことをしないでこのクラスを使用する方法を知りません。ですから、それは知識の不足や間違った質問の問題です。次回はもっと具体的な質問をします。 – LookingToLearn

答えて

1

は、彼らはあなたがこのような何かを許可しvariable methods (see example #2).さ:

class a { 
    function foo() { echo '1'; return $this; } 
    function bar() { echo '2'; return $this; } 
    function baz() { echo '3'; return $this; } 
} 
$a = new a(); 

$cond = true; 
$a->foo()->{($cond === true) ? 'baz' : 'bar'}(); 
// Prints 13 
$cond = false; 
$a->foo()->{($cond === true) ? 'baz' : 'bar'}(); 
// Prints 12 

は、ここでは、それぞれの要件を設定することができます方法です関数呼び出し。これは、以前のソリューションと同じように難しくない場合と同じように維持するのが難しいことに注意してください。あなたはおそらく何らかの種類の設定とReflectionClass's getMethods functionを使用したいと思うでしょう。

class a { 
    function foo() { echo '1'; return $this; } 
    function bar() { echo '2'; return $this; } 
    function baz() { echo '3'; return $this; } 
} 

function evaluateFunctionRequirements($object, $functionRequirements, $condition) { 
    foreach ($functionRequirements as $function=>$requirements) { 
    foreach ($requirements as $requiredVariableName=>$requiredValue) { 
     if (${$requiredVariableName} !== $requiredValue) { 
     continue 2; 
     } 
    } 
    $object->{$function}(); 
    } 
} 

$a = new a(); 
$functionRequirements = array('foo'=>array(), 'bar'=>array(), 'baz'=>array('condition'=>true)); 
$condition = true; 
evaluateFunctionRequirements($a, $functionRequirements, $condition); 
// Prints 123 
$condition = false; 
evaluateFunctionRequirements($a, $functionRequirements, $condition); 
// Prints 12 

注意:これはさらに困難$functionRequirementsアレイための機能を必要とするを維持するためにを添加しました。さらに、この初歩的な例では、1つの可能な条件がvarに渡され、より多くの$ requiredVariableName変数をfunc_get_argsで取得するための別の設定に更新されます。また、$ functionRequirements経由で渡されたメソッドがis_callable()であることを確認したい場合もあります。

+0

私はこれが今後も非常に維持可能ではないことに注意したいと思います。あなたがメソッド名などのいずれかをリファクタリングする必要があるとします。 –

+0

もっと良い方法があるとは思わないでしょう 彼はeval(推奨されません)に頼らざるを得ません。 – Buddhi741

+0

@KevinStichありがとう、これは近いです!また、条件が満たされている場合にのみ特定のメソッドを連鎖させるように質問を更新しました。これは実際に私の特定のユースケースです: – LookingToLearn

2

(あなたはここでQuick-Testがあります)あなたが

<?php 

    class Test{ 
     protected $prop1; 
     protected $prop2; 
     protected $prop3; 
     protected $prop4; 

     public function __construct() { 
     } 

     public function setProp1($prop1) { 
      $this->prop1 = $prop1; 
      return $this; 
     } 

     public function setProp2($prop2) { 
      $this->prop2 = $prop2; 
      return $this; 
     } 

     public function setProp3($prop3) { 
      $this->prop3 = $prop3; 
      return $this; 
     } 

     public function setProp4($prop4) { 
      $this->prop3 = $prop4; 
      return $this; 
     } 
    } 

    $a  = 2; 
    $b  = 7; 
    $cond = ($a > $b); 
    $cond2 = ($b > 50); 
    $test = new Test; 

    $test->setProp1(2)->{($cond === true) ? 'setProp4' : 'setProp3'}(11); 
    $test->setProp3(3)->{($cond2 === false) ? 'setProp2' : 'setProp4'}(6); 

    var_dump($test); 
    //YIELDS:: 
    object(Test)[1] 
     protected 'prop1' => int 2 
     protected 'prop2' => int 6 
     protected 'prop3' => int 3 
     protected 'prop4' => null 
関連する問題