一連のパラメーターを受け取り、SQLクエリの条件としてそれらに適用する関数があります。ただし、条件自体を含む単一の引数配列を優先しましたが、
_function searchQuery($params = array()) {
foreach($params as $param => $value) {
switch ($param) {
case 'name':
$query->where('name', $value);
break;
case 'phone':
$query->join('phone');
$query->where('phone', $value);
break;
}
}
}
_
私の同僚は、代わりにすべての引数を明示的にリストすることを好みました:
_function searchQuery($name = '', $phone = '') {
if ($name) {
$query->where('name', $value);
}
if ($phone) {
$query->join('phone');
$query->where('phone', $value);
}
}
_
彼の主張は、引数を明示的にリストすることにより、関数の動作がより明白になるということでした-謎の引数_$param
_が何であるかを見つけるためにコードを掘り下げる必要があるのとは対照的です。
私の問題は、10以上のような多くの引数を処理するときに、これが非常に冗長になることでした。推奨される方法はありますか?私の最悪のシナリオは、次のようなものです。
searchQuery('', '', '', '', '', '', '', '', '', '', '', '', 'search_query')
私の同僚は上記の例に適しています。あなたの好みは簡潔かもしれませんが、それはまた読みにくく、そのため保守性が低くなります。そもそもなぜ関数を書くのが面倒なのか、あなたの関数は何を「テーブルに持っていく」のか、という質問をしてください。私はそれが何をするのか、そしてそれをどのように行うのか、それを使うためだけに非常に詳細に理解しなければなりません。彼の例では、私はPHPプログラマーではありませんが、関数の宣言で十分に詳細を見ることができるので、その実装に自分自身を気にする必要はありません。
引数の数が多い限り、通常はコードのにおいと見なされます。通常、関数はやりすぎをしていますか?多数の引数が本当に必要な場合は、それらが何らかの方法で関連付けられており、1つまたはいくつかの構造またはクラス(おそらく住所の行などの関連アイテムの配列)に属している可能性があります。ただし、非構造化配列を渡しても、コードの臭いに対処することはできません。
私の答えは多かれ少なかれ言語にとらわれないです。
複雑なデータ構造(テーブル、レコード、ディクショナリ、オブジェクト...)で引数をグループ化する唯一の目的が、それらを全体として関数に渡すことである場合は、回避することをお勧めします。これにより、役に立たない複雑なレイヤーが追加され、意図がわかりにくくなります。
グループ化された引数がそれ自体で意味を持つ場合、その複雑なレイヤーは設計全体の理解に役立ちます。代わりに抽象化レイヤーと名付けます。
12個の個別の引数や1つの大きな配列の代わりに、相関データをグループ化する2つまたは3つの引数を使用するのが最良の設計であることに気付くでしょう。
あなたの場合は、同僚の方法がいいと思います。あなたがモデルを書いていて、私があなたのモデルを使ってそれらを開発していたなら。同僚のメソッドのシグネチャが表示され、すぐに使用できます。
一方、searchQuery
関数の実装を調べて、関数が期待するパラメーターを確認する必要があります。
searchQuery
が単一のテーブル内のみの検索に制限されているため、結合がない場合にのみ、このアプローチをお勧めします。その場合、私の関数は次のようになります。
function searchQuery($params = array()) {
foreach($params as $param => $value) {
$query->where($param, $value);
}
}
そのため、配列の要素が実際には特定のtableの列名であることをすぐに知っています。このメソッドを持つクラスがコードで表しています。
両方を実行してください。 array_merge
は、同僚の好みに応じて、関数の上部に明示的なリストを許可する一方で、必要に応じてパラメーターが扱いにくくならないようにします。
また、質問のコメントから@chiborgの提案を使用することを強くお勧めします-あなたが意図していることがはるかに明確です。
function searchQuery($params = array()) {
$defaults = array(
'name' => '',
'phone' => '',
....
);
$params = array_merge($defaults, $params);
if(!empty($params['name'])) {
$query->where('name', $params['name']);
}
if (!empty($params['phone'])) {
$query->join('phone');
$query->where('phone', $params['phone']);
}
....
}
また、クエリ文字列に似た文字列を渡し、 parse_str
(PHPを使用しているようですが、他の言語で他のソリューションが利用できる可能性があるため)メソッド内の配列に処理します。
/**
* Executes a search in the DB with the constraints specified in the $queryString
* @var $queryString string The search parameters in a query string format (ie
* "foo=abc&bar=hello"
* @return ResultSet the result set of performing the query
*/
function searchQuery($queryString) {
$params = parse_str($queryString);
if (isset($params['name'])) {
$query->where('name', $params['name']);
}
if (isset($params['phone'])) {
$query->join('phone');
$query->where('phone', $params['phone']);
}
...
return ...;
}
そしてそれを
$result = searchQuery('name=foo&phone=555-123-456');
http_build_query
連想配列から文字列に変換します(parse_str
します)。