関数の引数
引数のリストにより関数へ情報を渡すことができます。 このリストは、カンマで区切られた式のリストです。 引数の評価は、左から右の順番で行われます。
PHP は、値渡し(デフォルト)、 参照渡し、 デフォルト引数値 をサポートしています。また、 可変長引数リスト もサポートしてます。
例1 関数に配列を渡す
<?phpfunction takes_array($input){ echo "$input[0] + $input[1] = ", $input[0]+$input[1];}?>
PHP 8.0.0 以降では、引数リストの最後にカンマを付けることができます。 このカンマは無視されます。 これは、引数リストや変数名が長かったりした場合に、 引数を縦に並べるのに便利です。
例2 関数の引数リストの最後にカンマを付ける
<?phpfunction takes_many_args( $first_arg, $second_arg, $a_very_long_argument_name, $arg_with_default = 5, $again = 'a default string', // この最後のカンマは、8.0.0 より前では許されません。){ // ...}?>
PHP 8.0.0 以降では、オプションの引数の後に、必須の引数を続けることは、
推奨されなくなります。
一般的には、デフォルト値を削除することで解決できます。
このルールの唯一の例外は、Type $param = null
と書かれた引数です。
null をデフォルトにすることは、型が暗黙のうちに nullable であることを示しています。
この書き方はまだ許可されていますが、明示的に nullable 型を使うことを推奨します。
例3 オプションの引数の後に、必須の引数を続ける
<?phpfunction foo($a = [], $b) {} // PHP 8.0.0 より前function foo($a, $b) {} // PHP 8.0.0 以後function bar(A $a = null, $b) {} // PHP 8.0.0 でもまだ許可されていますfunction bar(?A $a, $b) {} // お勧めの書き方?>
引数の参照渡し
デフォルトで、関数の引数は値で渡されます。(このため、関数の内部で 引数の値を変更しても関数の外側では値は変化しません。)関数がその引 数を修正できるようにするには、その引数を参照渡しとする必要があり ます。
関数の引数を常に参照渡しとしたい場合には、関数定義において アンパサンド(&) を引数名の前に付加することができます。
例4 関数のパラメータの参照渡し
<?phpfunction add_some_extra(&$string){ $string .= 'and something extra.';}$str = 'This is a string, ';add_some_extra($str);echo $str; // 出力は 'This is a string, and something extra.' となります?>
デフォルト引数値
関数は、スカラー引数に関して次のように C++ スタイルのデフォルト値を 定義することができます。
例5 関数におけるデフォルトパラメータの使用法
<?phpfunction makecoffee($type = "cappuccino"){ return "Making a cup of $type.\n";}echo makecoffee();echo makecoffee(null);echo makecoffee("espresso");?>
上の例の出力は以下となります。
Making a cup of cappuccino. Making a cup of . Making a cup of espresso.
PHPでは、配列および特殊な型 null
をデフォルト値とすることも可能です。
例えば、
例6 スカラー型以外をデフォルト値として使用する
<?phpfunction makecoffee($types = array("cappuccino"), $coffeeMaker = NULL){ $device = is_null($coffeeMaker) ? "hands" : $coffeeMaker; return "Making a cup of ".join(", ", $types)." with $device.\n";}echo makecoffee();echo makecoffee(array("cappuccino", "lavazza"), "teapot");?>
デフォルト値は、定数式である必要があり、 (例えば) 変数やクラスのメンバーであってはなりません。
引数のデフォルト値を使用する際には、デフォルト値を有する引数はデ フォルト値がない引数の右側に全てある必要があることに注意して下さ い。そうでない場合、意図したような動作が行われません。次の簡単な コードを見てみましょう。
例7 関数の引数のデフォルト値の 間違った使用法
<?phpfunction makeyogurt($type = "acidophilus", $flavour){ return "Making a bowl of $type $flavour.\n";} echo makeyogurt("raspberry"); // 期待通りには動作しません。?>
上の例の出力は以下となります。
Warning: Missing argument 2 in call to makeyogurt() in /usr/local/etc/httpd/htdocs/phptest/functest.html on line 41 Making a bowl of raspberry .
ここで、上の例を次のコードと比べてみましょう。
例8 関数の引数のデフォルト値の 正しい使用法
<?phpfunction makeyogurt($flavour, $type = "acidophilus"){ return "Making a bowl of $type $flavour.\n";} echo makeyogurt("raspberry"); // 期待通り動作します?>
上の例の出力は以下となります。
Making a bowl of acidophilus raspberry.
注意:
リファレンス渡しの引数にもデフォルト値を指定できます。
可変長引数リスト
PHP は ...
を使った可変長引数をユーザー定義関数でサポートしています。
注意:
func_num_args(), func_get_arg(), func_get_args() 関数を使えば、可変長引数を実現できますが、 このテクニックは推奨されません。 なぜなら、
...
トークンが実装される前に使われていたものだからです。
引数リストに
...
トークンを含めることで、
その関数が可変長の引数を受け取ることを示せます。
引数は、指定した変数に配列として渡されます。次の例を参照ください。
例9 ...
を使った、可変長引数へのアクセス
<?phpfunction sum(...$numbers) { $acc = 0; foreach ($numbers as $n) { $acc += $n; } return $acc;}echo sum(1, 2, 3, 4);?>
上の例の出力は以下となります。
10
関数を呼び出すときに ...
を使うと、
配列変数や Traversable クラスを引数リストに含めることができます。
例10 引数での ...
の使用例
<?phpfunction add($a, $b) { return $a + $b;}echo add(...[1, 2])."\n";$a = [1, 2];echo add(...$a);?>
上の例の出力は以下となります。
3 3
通常の引数を、...
の前に指定することもできます。
この場合は、通常の引数リストにマッチしなかったのこりの引数が
...
による配列に追加されます。
...
トークンの前に、
型宣言 を付加することもできます。
型宣言がある場合、...
が取り込むすべての引数はその型に従わなければいけません。
例11 型宣言つきの可変長引数
<?phpfunction total_intervals($unit, DateInterval ...$intervals) { $time = 0; foreach ($intervals as $interval) { $time += $interval->$unit; } return $time;}$a = new DateInterval('P1D');$b = new DateInterval('P2D');echo total_intervals('d', $a, $b).' days';// これは失敗します。null は DateInterval オブジェクトではないからです。echo total_intervals('d', null);?>
上の例の出力は以下となります。
3 days Catchable fatal error: Argument 2 passed to total_intervals() must be an instance of DateInterval, null given, called in - on line 14 and defined in - on line 2
可変長引数の
参照渡し
もできます。その場合は、...
の前にアンパサンド
(&
) を付加します。
古いバージョンの PHP
可変長引数に関して特別な構文は必要としません。しかし、関数の引数にアクセスするには func_num_args()、func_get_arg() および func_get_args() といった関数を使う必要があります。
先ほどの最初の例を、古いバージョンの PHP で実装すると、以下のようになります。
例12 可変長引数へのアクセス (古いバージョンのPHP)
<?phpfunction sum() { $acc = 0; foreach (func_get_args() as $n) { $acc += $n; } return $acc;}echo sum(1, 2, 3, 4);?>
上の例の出力は以下となります。
10
名前付き引数
既にある、位置を指定した引数を拡張する形で、PHP 8.0.0 から名前付き引数が導入されました。 名前付き引数は、位置ではなく、名前ベースで引数を渡すことを可能にします。 これによって、引数の意味が自己文書化(self-documenting)され、 引数を任意の順番で渡せるようになり、任意のデフォルト値を持つ引数をスキップできるようになります。
名前付き引数は、引数の名前の後にコロンを付けたものを、値の前に付けることで指定します。 引数の名前にに予約語を使うことも許されています。 引数の名前は識別子でなければならず、動的に指定することは出来ません。
例13 名前付き引数の文法
<?phpmyFunction(paramName: $value);array_foobar(array: $value);// 以下の書き方はサポートされていませんfunction_name($variableStoringParamName: $value);?>
例14 位置を指定した引数と、名前付き引数
<?php// 位置を指定した引数の場合:array_fill(0, 100, 50);// 名前付き引数の場合:array_fill(start_index: 0, num: 100, value: 50);?>
名前付き引数は、渡す順番は関係ありません。
例15 上と同じ例を、引数の順番を変えて渡す
<?phparray_fill(value: 50, num: 100, start_index: 0);?>
名前付き引数は、位置を指定した引数と組み合わせることが出来ます。 そうした場合、名前付き引数は、位置を指定した引数の後に置かなければいけません。 オプションの引数だけをいくつか、指定することもできます。 その場合も、名前付き引数の順番は関係ありません。
例16 位置を指定した引数と、名前付き引数を組み合わせる
<?phphtmlspecialchars($string, double_encode: false);// 上記は、以下と同等です。htmlspecialchars($string, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);?>
同じ引数を複数回渡すと、Error 例外が発生します。
例17 同じ引数を複数回渡すと、Error 例外が発生する
<?phpfunction foo($param) { ... }foo(param: 1, param: 2);// Error: Named parameter $param overwrites previous argumentfoo(1, param: 2);// Error: Named parameter $param overwrites previous argument?>