web-dev-qa-db-ja.com

PHP関数は引数の配列を受け入れる必要がありますか、それとも明示的に引数を要求する必要がありますか?

PHP私が取り組んでいるWebアプリケーションでは、2つの可能な方法で定義された関数が表示されます。

アプローチ1:

function myfunc($arg1, $arg2, $arg3)

アプローチ2:

// where $array_params has the structure array('arg1'=>$val1, 'arg2'=>$val2, 'arg3'=>$val3)
function myfunc($array_params)

あるアプローチを別のアプローチよりもいつ使用すべきですか?システム要件が変化し続け、そのためmyfuncの引数の数が変化し続ける場合、アプローチ1では多くのメンテナンスが必要になる可能性があります。

37
John

システムが頻繁に変化するので、インデックス付き配列を使用することが最善の解決策である場合、これはあなたの心配の中で最も少ないと思います。 :-)

一般に、関数/メソッドはあまり多くの引数を取るべきではなく(5プラスまたはマイナス2が最大です)、名前付き(理想的には type hinted )引数の使用に固執する必要があると思います。 (引数のインデックス付き配列は、オプションのデータが大量にある場合にのみ意味があります-良い例は構成情報です。)

@Pekkaが言うように、引数の配列を渡すことは、文書化するのに苦労する傾向があり、したがって、nか月以内に他の人/あなた自身が維持するのは困難です。

Update-ette ...

ちなみに、頻繁に言及された本 Code Complete は、そのような問題をかなり詳細に調べています-私が強くお勧めする素晴らしい本です。

30
John Parker

Params配列(他の言語で「名前付き引数」と呼ばれるものの代理)を使用するのは素晴らしいです-私はそれを自分で使用したいのですが、かなり大きな欠点があります。その結果、IDEは、関数またはメソッドの名前を入力するときにヒントを与えることができません。

17
Pekka

オプション引数の配列を使用すると、関数のデフォルトのセットをオーバーライドしたい場合に便利です。これは、多くの異なる構成オプションを持つオブジェクト、または単なる情報のダムコンテナーであるオブジェクトを構築するときに役立ちます。これは主にRubyの世界からピックアップしたものです。

例として、Webページのビデオのコンテナを構成する場合があります。

function buildVideoPlayer($file, $options = array())
{
  $defaults = array(
    'showAds' => true,
    'allowFullScreen' = true,
    'showPlaybar' = true
  );

 $config = array_merge($defaults, $options);

 if ($config['showAds']) { .. }
}

$this->buildVideoPlayer($url, array('showAds' => false));

$ optionsの初期値は空の配列であるため、それを提供するかどうかは任意であることに注意してください。

また、この方法では、$ optionsは常に配列であり、それらのキーにはデフォルトがあることがわかっているため、引数を参照するときにis_array()またはisset()を常に確認する必要はありません。

13
Bryan M.

最初のアプローチでは、関数のユーザーに必要なすべてのパラメーターを提供することを強制します。 2番目の方法では、必要なものがすべて揃っていることを確認できません。私は最初のアプローチを好みます。

5
user235064

渡すパラメーターを論理的にグループ化できる場合は、パラメーターオブジェクト(Refactoring、Martin Fowler、p295)を使用することを考えることができます。そのため、さらにパラメーターを追加する必要がある場合は、追加するだけで済みます。パラメータクラスにさらにフィールドを追加すると、既存のメソッドが壊れることはありません。

4

それぞれの方法には長所と短所があります。

  • 変更される可能性が低く、引数が少ない単純な関数である場合は、明示的に述べます。

  • 関数に多数の引数がある場合、または将来大幅に変更される可能性がある場合は、引数の配列をキーとともに渡し、それを使用します。これは、いくつかの引数を頻繁に渡すだけでよい関数がある場合にも役立ちます。

たとえば、引数ではなく配列を選択する場合の例は、フォームフィールドを作成する関数がある場合です。私が望む可能性のある引数:

  • タイプ
  • クラス
  • ID
  • スタイル
  • オプション
  • 必要とされている

そして、私はこれらのいくつかを渡す必要があるだけかもしれません。たとえば、フィールドがtype = textの場合、オプションは必要ありません。必ずしもクラスやデフォルト値が必要なわけではありません。このように、トンの引数を持つ関数シグネチャを持たず、常にnullを渡すことなく、引数のいくつかの組み合わせで渡す方が簡単です。また、HTML 5が長年標準になったとき、オートコンプリートをオンまたはオフにするなど、可能な引数を追加したいと思うかもしれません。

3
GSto

私はこれが古い記事であることを知っていますが、私のアプローチを共有したいと思います。変数が型で論理的に接続されている場合は、変数をクラスにグループ化し、それらのオブジェクトを関数に渡すことができます。例えば:

      class user{
           public $id;
           public $name;
           public $address;
           ...
      }

そして呼び出す:

      $user = new user();
      $user->id = ...
      ...

      callFunctions($user);

新しいパラメータが必要な場合は、クラスに追加するだけでよく、関数のシグネチャを変更する必要はありません。

0
Aris