ほとんどのプログラミング言語には関数に値を渡す引数という仕組みが存在します。
その中でもPHPでは複数の引数を配列で受け取るfunc_get_argsという関数が用意されています。また、PHP5.6以上からは別の方法が推奨されていますので、あわせて紹介したいと思います。
目次
引数を使って関数へ値を渡す基本形
まずは引数の基本形について学びましょう。
以下の通りArgTest関数に4つの文字列データを渡しています。
1 2 3 4 5 |
ArgTest("This", "is", "a", "pen"); function ArgTest($a1, $a2, $a3, $a4){ print $a1 . " ". $a2 . " ". $a3 . " ". $a4 ."\n"; } |
ArgTest関数では4つの引数を$a1, $a2, $a3, $a4の4つの変数で受け取り出力させています。
実行結果は以下の通りです。
1 |
This is a pen |
これが引数の基本形です。
PHPに限らずほとんどのプログラミング言語で同じような渡し方をしています。
複数の引数を配列化したい
上記のように複数の引数を配列化したい場合、どのようにしたら良いのでしょうか。
PHPの場合は以下のようにArray関数を使って配列化すれば良いわけですね。
1 2 3 4 5 6 7 8 9 10 |
ArgTest("This", "is", "a", "pen"); function ArgTest($a1, $a2, $a3, $a4){ $args = array($a1, $a2, $a3, $a4); for($i=0; $i<count($args); $i++){ print $args[$i] . " "; } print ".\n"; } |
また、引数の数を固定化するのではなく、状況により不特定数の引数を渡したいケースがあった場合には上記の方法では対応できません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// OK ArgTest("This", "is", "a", "pen"); // 以下はエラーになる ArgTest("These", "are", "pens"); ArgTest("I", "have", "a", "pen.", "I", "have", "a", "apple"); function ArgTest($a1, $a2, $a3, $a4){ $args = array($a1, $a2, $a3, $a4); for($i=0; $i<count($args); $i++){ print $args[$i] . " "; } print ".\n"; } |
しかし、PHPではより簡単に配列化が実現でき、不特定数の引数に対応できる仕組みが用意されています。
PHPで func_get_args を使う方法
PHPではfunc_get_args関数が用意されていて、渡された引数を配列で受け取ることができます。このとき、少し違和感があると思いますが関数のカッコ内には受け側の変数をセットする必要がありません。
1 2 3 4 5 6 7 8 9 10 11 |
ArgTest("This", "is", "a", "pen"); function ArgTest(){ $args = func_get_args(); $count = func_num_args(); for($i = 0; $i < $count; $i++) { print $args[$i] . " "; } print ".\n"; } |
出力結果は基本形と同じく以下の通りとなります。
1 |
This is a pen |
func_get_args関数によって$argsに配列化された引数がセットされます。また、次の行にあるfunc_num_args関数で配列の要素数が取得できます。
1 2 3 4 |
// 引数の配列化 $args = func_get_args(); // 引数の数を取得 $count = func_num_args(); |
このfunc_get_args関数利用のもう1つの利点として、引数を渡さなくても受け入れられるという点です。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// これでもエラーにはならない ArgTest(); function ArgTest(){ $args = func_get_args(); $count = func_num_args(); // $count=0なのでforループ内は処理されない for($i = 0; $i < $count; $i++) { print $args[$i] . " "; } print ".\n"; } |
最初に紹介した引数の基本形では、関数に定めた引数と同じ数の値を渡す必要があります。func_get_args関数を利用するとその制約はありません。しかし、同時に注意しないと思わぬバグを入れてしまう危険性があるので注意しましょう。
可変長引数(…トークン)を使う方法
引数を配列化するもう1つの方法について紹介します。
それは可変長引数と言って、関数のカッコ内に(…変数)という形式で表現します。
以下が可変長引数の例になります。
1 2 3 4 5 6 7 8 |
ArgTest("This", "is", "a", "pen"); function ArgTest(...$args){ for($i=0; $i<count($args); $i++){ print $args[$i] . " "; } print ".\n"; } |
出力結果はfunc_get_args関数を使用した上の例と同じです。
1 |
This is a pen |
引数と要素数を取得する行がない分、こちらの方がすっきりとしたコードになっているかと思います。
また、func_get_args関数と同じく引数を渡さなくてもエラーにはなりません。
1 2 3 4 5 6 7 8 9 10 |
// これでもエラーにはならない ArgTest(); function ArgTest_(...$args){ // count($args)=0なのでforループ内は処理されない for($i=0; $i<count($args); $i++){ print $args[$i] . " "; } print "\n"; } |
func_get_argsと可変長引数とどちらを使えば良いのか
上記の通り、func_get_args関数の使用例と可変長引数の使用例とで、違いがまったく見られません。
では、いったいどちらを使えばよろしいのでしょうか。
その答えは公式サイトに載っています。
https://www.php.net/manual/ja/functions.arguments.php#functions.variable-arg-list
func_num_args(), func_get_arg(), func_get_args() 関数を使えば、可変長引数を実現できますが、 このテクニックは推奨されません。 なぜなら、… トークンが実装される前に使われていたものだからです。
func_get_args関数はレガシーな機能のようで、PHP5.6以降に可変長引数(…トークン)登場以来、非推奨となっているようです。
あらゆるPHPバージョンに対応させなければいけない場合は、func_get_args関数を使うべきでしょう。しかし、PHP5.6以降のバージョンとわかっている環境で使う場合には可変長引数の使用を推奨します。
まとめ
いかがでしょうか。
引数という関数へのデータの受け渡す機能は、ほとんどのプログラミング言語で存在します。
今回紹介した不特定数の引数を配列で受け取るという方法は、他のプログラミング言語ではめずらしいPHPの特徴の1つとも言えます。
また、func_get_argsと可変長引数の2通り存在するのも、歴史が長く現在まで仕様変更されつつ長きに愛され続けてきたPHPならではのことではないでしょうか。
ぜひ利用してみてください。