関数/メソッドのオプションを柔軟に受け渡す

Tips公開が流行ってるみたいなのでそれに乗ってみます。

関数やメソッドの引数が多くなると、呼び出し側で何をやっているのか分からない表記になりがちです。関数を定義する際もどれを省略可能にするかで引数の順番を悩んだりして…。


たとえばこんな関数があったとします。

function getItemsByMode($key, $mode = DEFAULT_MODE, $limit = 0, $offset = 0) {
  ...
}

呼び出す側は

$items = getItemsByMode($myKey, MODE_A, 20);

だったり

$items = getItemsByMode($myKey, MODE_A, 20, 40);

なわけで、20と40のどっちがlimitか分かりにくいことこの上ないです。そこで今回の方法となるわけですが、その前にひとつ前準備。今回は引数に連想配列を使うので、連想配列用の便利関数を作ります。

function array_val(&$data, $key, $default = null) {
    if (!is_array($data)) {
        return $default;
    }
    return isset($data[$key])? $data[$key]: $default;
}

要は連想配列のキーチェックをお手軽に済ます関数です。さて準備完了。では先ほどの関数をこのarray_val()を使って書き換えます。

function getItemsByMode($key, $options = null) {
    // オプション解析
    $mode = array_val($options, 'mode', DEFAULT_MODE);
    $limit = array_val($options, 'limit', 0);
    $offset = array_val($options, 'offset', 0);
  ...
}

これで引数の省略可能部分を自由に指定できるようになりました。呼び出す側も

$items = getItemsByMode($key1, array('mode' => MODE_A));
$items = getItemsByMode($key2, array('offset' => 40, 'limit' => 20));

というように、必要な引数のみ明示的に指定できます。これでコードも分かりやすくなってばっちり。