2011-07-04 24 views
4

私は自分のウェブサイト上で検索するだけのクラスとメソッドを作成しました。あまりにも多くのパラメータ、検索パラメータがあります。私のコントローラはフォームからデータを取得し、モデルに渡します。PHPよくある実践 - あまりにも多くのパラメータを持つメソッド

public function search($name, $age, $foo, ... $bar, $lorem) { 

この種の方法のヒントはありますか?あまりにも多くのパラメータを持つメソッドについては、おそらく良い習慣です。おかげさまで

EDIT:

パラメータは、検索のためのものです... $名はように$の年齢 の値を持つ人々を検索しなければならない$名 $時代の価値を持つ人々を検索する必要があります...のような 何かSQLのWhere句

もう一度おねがいします。

+2

を。 –

+0

@MarcB:答えとして投稿してみませんか? –

+2

通常、これはメソッドが複雑すぎる/強力であることを示す指標です。この機能を無効にする必要があります。 –

答えて

9

DarhazerZanathelはすでに良い答えを与えた、と私はあなたに一つのことを示したい:流れるようなインターフェイスでセッターを。すべてのパラメータがオプションの場合のみ。

$finder-> 
setName($name)-> 
setAge($age)-> 
setFoo($foo)-> 
setBar($bar)-> 
setLorem($lorem)-> 
search(); 

または

$query = new SearchQuery($required_argument); 
$query->setAge($optional)->setLorem($optional); 

$finder->search($query); 

ちょうど私が/多くのパラメータを持っているかもしれない機能のための配列を使用したいとセッターの体内にreturn $this;

+0

偉大な答え:D ありがとう。 – thom

1

多くの名前と値のペアを持つパラメータとして配列を受け入れるようにします。次に、extract($paramsArray)を使用して、配列内のすべての名前を$変数として作成できます。

+0

それは私のやり方ですそれ。 –

2

あなたがキーに物事を詰めることができ=>値に基づく配列

例:

$params = array("Name"=>"Bob", "Age"=32.....); 
Class->search($params); 
public function search($params) { 
    // access keys 
} 

この方法は非常に簡単に任意の配列を渡すことができますので、間違って使用される可能性があるため、少し疲れています配列の内容を検証するために、他のメソッド呼び出しで検証が必要な場合があります。

編集:コメントの中で、いくつかの議論があったので....ここで新しいクラスを作成し、この

を行うための別の方法があります!名前の年齢など、その他の人口統計を含むユーザー・クラス。とにかく他の場所にあるものを使うでしょう。

オブジェクトを渡すか、引数

$object = new Object(); 
SearchClass->search($object) 

public function search(Object $object){ 
    // Do junk here 
} 
+0

メソッドに引数を渡すことはいつでも可能です。配列を使用しても、それを「間違って」使用しやすくなりません。 – phant0m

+1

これはオプションのパラメータでは問題ありませんが、必要とされるキーが何であるかを確認するためにメソッドの本体をチェックする必要があるため、私の意見では必須パラメータには適していません。また、与えられたパラメータが渡されたかどうかをチェックしなければならないので、本体を長くします(デフォルト値を提供します) –

+0

@ phant0m関数内にREQUIREDパラメータの定義済みセットがある場合、パラメーター。配列を使用することで、関数が正しく実行するために必要なパラメータの数を間違えることがあります。私が言ったように、あなたが間違っている場合は、例外をスローすることができるように、上記の必須パラメータの検証メソッドを作成する必要があります。したがって、誤用しやすくなります。特に、クライアントがコードを使用していて、それに精通していない場合。 – Trevor

1
+0

なぜ誰かが-1に投票したのですか? – phant0m

+0

-1、それは何でしたか? –

+1

既に-2(と私の+1)。 @ダーハザー、あなたの答えは正しいですが、多分、あなたはリンクに3つ以上の単語を書くことができますか? :) –

2

としてオブジェクト私はあなたがするプロパティなど、すべての必要なパラメータが含まれていますオブジェクトを渡すところ、value objectsに最も近い比喩を使用したいです関数。

<?php 
class FilterVO { 
    public $id; 
    public $name; 
    // etc ... 
} 

class SomeCollection { 
    public function FilterResults(FilterVO $prefs) { 
     // got all the goodies in here 
    } 
} 
?> 
+1

check $ prefsの代わりに、次のようなことができます:public function FilterResults(FilterVO $ prefs)...ありがとう。 – thom

+0

質問の作成者が回答を訂正すると良いです:) –

+0

完了しましたOZ_ :) – thom

3

を書き、fluent interfaceを作成します。この種のアプローチは、パラメータのほぼ無限の拡張を可能にし、func_get_args()のようなものを使用するよりも簡単でより良い方法です。

public function search(array $options = array()) 
{ 
    $defaults = array(
     'name' => null, 
     'age' => null, 
     'order' => null, 
     'limit' => null, 
     'offset' => null, 
    ); 
    $options = array_merge($defaults, $options); 

    extract($options); 

    $select = $this->select(); 

    if (!is_null($name)) { 
     $select->where('name = ?', $name); 
    } 
    if (!is_null($age)) { 
     $select->where('age = ?', $age, Zend_Db::INT_TYPE); 
    } 
    if (!is_null($order)) { 
     $select->order($order); 
    } 
    if (!is_null($limit) || !is_null($offset)) { 
     $select->limit($limit, $offset); 
    } 

    $results = $this->fetchAll($select); 

    return $results; 
} 

...またはあなたがオブジェクト指向のアプローチを使用することができます:配列の要素として、各パラメータを含む単一の配列を渡し

class SearchQuery 
{ 
    public function __construct(array $options = null) 
    { 
     if (!is_array($options)) { 
      return; 
     } 

     if (array_key_exists('name', $options)) { 
      $this->setName($options['name']); 
     } 
     if (array_key_exists('age', $options)) { 
      $this->setAge($options['age']); 
     } 
    } 

    public function setName($name) 
    { 
     if (!is_string($name)) { 
      throw InvalidArgumentException('$name must be a string'); 
     } 

     $this->_name = $name; 

     return $this; 
    } 

    public function setAge($age) 
    { 
     if (!is_numeric($age) || $age <= 0) { 
      throw new InvalidArgumentException('$age must be a positive integer'); 
     } 

     $this->_age = $age; 

     return $this; 
    } 
} 

// then you can use dependency injection in your main search class 

class SearchService 
{ 
    public function search(SearchQuery $query) 
    { 
     // search 
    } 
} 
関連する問題