PHPの名前付き引数、使っていますか!?私は実務でまだ使えていません。個人開発でも何回か使った程度。使う際は「あれ、どうだったっけな」と調べながら使うレベルです。
つまり、全く身についてないということですね。
PHP3系からですから、従来の書き方が身に染みついていて、覚えられない……。
私だけではなく、同様の方はそこそこいらっしゃるのではないでしょうか。
というわけで、すぐ忘れる名前付き変数について、忘れてもすぐ思い出せるように。そして身につけて実務でも使えるように、この度まとめることにしました。
名前付き引数とは!?
名前付き引数は、PHP 8.0.0 から導入された機能です。
名前付き引数を使用することで、関数やメソッドを呼び出す際に、引数の名前を指定して値を渡すことができます。つまり引数の順序を気にせずに、関数を呼び出すことが可能となります。
文法
言葉で読むと分かりづらいですね。コードで見た方が早いです。
<?php
// 関数の定義は従来と同じ
function function_name($param) {
echo $param;
}
// 呼び出し元が従来と違う
function_name(param: "test");
// 出力: test
上記のように、呼び出し元でparam: "test"
という引数を与えることで、関数では$param = "test"
として代入されます。
もちろん、複数の引数を与えられます。
<?php
function sampleFunction($param1, $param2, $param3) {
// 処理
}
// 名前付き引数を使用して関数を呼び出す
sampleFunction(param1: 1, param2: 2, param3: 3);
// 以下の普通に呼び出したケースと同じ
// sampleFunction(1, 2, 3);
ここでは呼び出し側で、param1: 1, param2: 2, param3: 3
とすることにより、関数では$param1 = 1, $param2 = 2, $param3 = 3
が与えられるということです。
つまり定義の問題ではなく、呼び出す際のテクニックということですね。
使えるところ
以下で名前付き引数が使えます。
- 関数
- クラスのコンストラクタ
- メソッド
本ページでは無駄なコードを省くため関数の例としていますが、多くの場合はクラス内のメソッドで使うことになるのかなと思います。
メリット
名前付き引数の導入により、以下のようなメリットが得られます。
- 可読性の向上:
引数の名前を明示的に指定することで、関数の呼び出し時のコードがより読みやすくなることがあります(必ずしもそうとは言えないことに注意)。 - 引数の順序に縛られない:
引数の順序を気にせず関数を呼び出せるので非常に便利です。 - デフォルト値との相性:
デフォルト値を持つ引数をスキップして、特定の引数だけを指定して関数を呼び出すことが容易になります。
注意点もあるので、一通りご案内した後にご紹介します。
基本的な使い方
先ほどのコード例は、文法をざっくりとご紹介するために実用的ではないコードでした。
ここからもう少しまともなコード例と共に、使い方をご紹介します。
シンプルな関数と名前付き引数
以下のように使うことで、名前が"Alice"
、年が30
ということが明確に表現できます。
<?php
function greet($name, $age) {
return "こんにちは、私の名前は{$name}で、{$age}歳です。";
}
echo greet(name: "Alice", age: 30);
// 出力: こんにちは、私の名前はAliceで、30歳です。
通常の引数は順番が重要になってきますが、名前付き引数なら、以下の様に逆にしても同じです。
<?php
function greet($name, $age) {
return "こんにちは、私の名前は{$name}で、{$age}歳です。";
}
echo greet(age: 30, name: "Alice");
// 出力: こんにちは、私の名前はAliceで、30歳です。
デフォルト値との組み合わせ
名前付き引数は、デフォルト値を持つ引数と組み合わせることができます。これにより、特定の引数だけをオーバーライドして関数を呼び出すことが可能となります。
<?php
function introduce($name = "John", $hobby = "読書") {
return "{$name}は{$hobby}が好きです。";
}
echo introduce(hobby: "テニス");
// 出力: Johnはテニスが好きです。
これまでの方法では、$hobbyだけに値を設定することはできませんでした。以下の様に、Johnまで引数に指定しなければならなかったのです。
<?php
function introduce($name = "John", $hobby = "読書") {
return "{$name}は{$hobby}が好きです。";
}
echo introduce('John', "テニス");
// 出力: Johnはテニスが好きです。
このようなケースが発生する場合では、名前付き引数の方が便利に使えますね。
名前付き引数と位置引数の組み合わせ
PHPの名前付き引数は、通常の位置引数と組み合わせて使用することもできます。ただし、名前付き引数は位置引数の後に指定する必要があります。
<?php
function purchaseItem($itemName, $quantity, $shippingMethod = '通常配送', $wrapping = '無し') {
return "{$itemName}を{$quantity}個、{$shippingMethod}で、ラッピング:{$wrapping}で購入しました。";
}
echo purchaseItem('ノートパソコン', 2, wrapping: 'ギフト');
// 出力: ノートパソコンを2個、通常配送で、ラッピング:ギフトで購入しました。
この例では、最初の2つの引数は(マストな)位置引数として、最後の引数は名前付き引数として指定しています。
マストな引数は通常の位置引数。オプションは名前付き引数。……というような使い方が可能です。
注意点
実例を通じて、多くのメリットがあることがわかりました。そんな便利な名前付き引数ですが、万能ではありません。
デメリット的な側面もありますので、理解&注意して使う必要があります。
明確な引数名の選択
関数の引数の名前は、あらかじめその目的や役割を明確に示すものを選ぶことが重要です。それができている場合にのみ、関数の呼び出し時にその意味が直感的に理解できます。
逆に変な名前をつけてしまうと大変です。
以下の様な抽象的なケースでは「なにやってんじゃ」となります。
<?php
function processData($hoge, $val) {
// ...
}
// 呼び出し時
processData(hoge: $hoge, val: $val);
後から引数名を変更しづらい
後から引数名を変更すると、呼び出し元も変更しなければならないので注意が必要です。私もこれがちょっといやでした。
どのような影響があるか分からない……という場合は、使うのはちょっとリスキーに感じます。
特に特にライブラリやフレームワークの開発者としては、ユーザーに影響を与える可能性があります。後方互換性を考えると、使い所は慎重になると思います。
他の言語との違い
C#・Ruby・Pythonなどでも名前付き引数は使用できるようです。ですので使いこなせるようになっておけば、他の言語を学ぶ際にも便利です。
ただ、言語ごとの仕様の違いをきちんと認識しておく必要がありそうですね。仕様の違いで不測の事態に陥ることはよくあるからです。
複数の言語で仕事をしていると、ちょっとした違いでうまく動かなかったり、頭がごちゃごちゃしたりしませんか。
まとめ
PHP 8.0のリリースとともに導入された名前付き引数は、コードの可読性と柔軟性を大きく向上させる機能として迎えられました。
特に多くの引数を持つ関数や、デフォルト値を多用する関数の呼び出しにおいて、その利点は顕著です。
しかし、従来の引数を完全に置き換えるものではなく、適材適所で使うことが重要です。
保守的な私は、変数名を変えると問題が発生することを考え、なかなか実務では使えていませんでした。……が、適した場所では積極的に使っていきたい機能です。
改めてしっかりと学んだので、実務でも使い所を模索していこうと思います。
コメント