phpの可変長引数についていろいろ

仕事でphpを書くようになって、今まで触れていた言語とのいろんなお作法の違いによく躓く毎日です><
結構長時間ハマった部分があったので、メモメモ。

今回は、phpで可変長引数を受け取ったり渡したりする方法について、JavaScriptとの対比で見ていきます。

先ずは、受け取る方から。

これはいろんなWebページで紹介されてますねー。
addAllは、引数の総和を返す関数です。

JavaScript
function addAll() {
	var result = 0;
	var args = arguments;
	var i = 0;
	var imax = args.length;
	for (; i < imax; i++) {
		result += args[i];
	}
	return result;
}

console.log(addAll(1, 2, 3, 4));	// output 10
php
<?php
function addAll() {
	$result = 0;
	$args = func_get_args();
	$i = 0;
	$imax = count($args);	// ((func_num_args()との違いを後で調べる。))
	for (; $i < $imax; $i++) {
		$result += $args[$i];
	}
	return $result;
}

print(addAll(1, 2, 3, 4));	// output 10
?>

ここで、これらの関数の引数は配列ではありません

次、渡す方いきます。

渡す方と言っても、関数呼ぶだけならそのまま

addAll(1, 2, 3, 4);

で終わってしまいますね><

ここでは自身も可変長引数を取り、内部でaddAllを呼ぶ関数を書いてみます。*1
wappedAddAllは、引数の総和を3乗して返す関数です。

JavaScript
function wrappedAddAll() {
	var args = arguments;
	var sum = addAll.apply(null, args);
	return Math.pow(sum, 3);
}

console.log(wrappedAddAll(1, 2, 3, 4));	// output 1000
php
<?php
function wrappedAddAll() {
	$args = func_get_args();
	$sum = call_user_func_array('addAll', $args);
	return pow($sum, 3);
}

print(wrappedAddAll(1, 2, 3, 4));	// output 1000
?>

これが出来るとなにが便利か。

実はこのcall_user_func_array、組み込み関数(ビルトインファンクション・定義済み関数)やクラスメソッド、インスタンスメソッドにも使えてしまうんです。

例えば、mysqli_stmt::bind_param(このメソッドは可変長引数を取ります。)をラップして、多次元配列を受け取ってプリペアドステートメントに順次投げるなんてこともできます。
PDO::executeみたいな。

自分は、この"user"に惑わされてスルーしてしまったが為に、かなりの時間をロスしてしまいました。
何故わざわざ"user"なのか、ご存知の方がいらっしゃいましたらコメント下さい><

*1:参照渡しだの値渡しだの参照の値渡しだの、applyはthisがナンダカンダだのというのは今回の趣旨から外れるのでここでは言及しません。