PHPで可変引数を使う

phpで引数を受け取る関数を定義する時、普通は、


function add($a, $b) {
    return $a + $b;
}

といった感じで定義しますが、実は次のようにも書けます。


function add() {
    $args = func_get_args();
    return $args[0] + $args[1];
}

func_get_args()で、関数に渡された引数が配列で返されます。

この書き方だと、引数の数も限定されません。


function add() {
    $args = func_get_args();
    $sum = 0;
    foreach ($args as $v) {
        $sum += $v;
    }
    return $sum;
}

echo add(10, 20, 30, 40, 50);	// 150が出力される。

関数定義で引数を宣言しても構いません。


function add($base) {
    $args = func_get_args();
      :
}

ただ、この場合でもfunc_get_args()は全ての引数を返すので、$baseと$args[0]は同じ値になります。


function add($base) {
    $args = func_get_args();
    array_shift($args);		// 第一引数をスキップ
    foreach ($args as $v) {
        $base += $v;
    }
    return $base;
}

引数があると関数の目的を把握し易いので、特に必要が無ければ通常は引数つきの関数を使った方がいいと思います。

可変引数を受け付ける代表的な関数というと、printf()系がありますね。


printf("%s+%s=%d", "a", "b", $a+$b);

自分で作った関数に渡された可変引数を、そのままprintfに渡すことは出来るでしょうか。


function func() {
    $args = func_get_args();
    printf($args);	// これはうまくいかない。
}

残念ながら、これではうまく動きません。

配列の中身を個々の引数として関数を呼び出すには、call_user_func_array()を使います。

call_user_func()の配列引数版です。


function func() {
    $args = func_get_args();
    call_user_func_array("printf", $args);
}

func("%s+%s=%d", "a", "b", $a+$b);

例えば、次のような書き方もできます。


function add() {
    $args = func_get_args();
    array_unshift($args, "%s + %s = %d");
    call_user_func_array("printf", $args);
}

$a = 10; $b = 20;
add("a", "b", $a+$b); // a + b = 30と表示される。

call_user_func〜()を使った関数の呼び出し方は、直接関数を呼び出すより速度は落ちますが、場合によっては便利に使えそうです。

フレーワーク等では多用されてますね。