グローバルナビゲーションへ

本文へ

フッターへ

お役立ち情報Blog



PHP8で名前付き引数が使えるようになっていたのでまとめてみた

前回の記事ではPHP8にて実装されたmatch式を紹介しました。
PHP8の変更点を調べていたところ、ついに名前付き関数が使えるようになったようなのでまとめてみようと思います。

名前付き関数とは?

既にある、位置を指定した引数を拡張する形で、PHP 8.0.0 から名前付き引数が導入されました。 名前付き引数は、位置ではなく、名前ベースで引数を渡すことを可能にします。 これによって、引数の意味が自己文書化(self-documenting)され、 引数を任意の順番で渡せるようになり、任意のデフォルト値を持つ引数をスキップできるようになります。PHPドキュメント

とても便利そう!ひとつずつ見ていってみます。

名前付き関数の利点

引数の意味が自己文書化(self-documenting)される

下記の例では  $toArray 関数を使用している側ではどの引数がどのように使われているかが明確ではありません。
そのため今までは該当の関数を見に行ったりコメントを残したり等の手間がかかっていました。

<?php

$toArray = function($title='タイトルが入ります', $detail='概要が入ります', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray('hoge', 'fugapiyo', 10)); // こちらからでは$toArray関数でどのように使われるかが明確でない
/*
array(3) {
  ["id"]=>
  int(10)
  ["title"]=>
  string(4) "hoge"
  ["detail"]=>
  string(8) "fugapiyo"
}
*/
?>

名前付き関数を使って書き換えると下記のようになります。
引数がどのように使われるか明確になり、使用する側からでもある程度どのような処理が行われているかが推測できるようになるため、可読性が増します。

<?php

$toArray = function($title='タイトルが入ります', $detail='概要が入ります', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray(title:'hoge', detail:'fugapiyo', id:10)); // 引数がどのように使われるか明確!
/*
array(3) {
  ["id"]=>
  int(10)
  ["title"]=>
  string(4) "hoge"
  ["detail"]=>
  string(8) "fugapiyo"
}
*/
?>

引数を任意の順番で渡せるようになる

見出し通りですが、名前付き関数を使うことで引数の順番を無視して渡すことができるようになります。
下記の例では引数の順番を間違えてしまったために想定と異なる返り値になってしまっています。

<?php

$toArray = function($title='タイトルが入ります', $detail='概要が入ります', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray(10, 'title', 'detail')); // 引数の順番を間違えてしまった!
/*
想定と異なる返り値になってしまっている…
array(3) {
  ["id"]=>
  string(6) "detail"
  ["title"]=>
  int(10)
  ["detail"]=>
  string(5) "title"
}
*/
?>

名前付き関数を使って書き直すと下記のようになります。
順番を間違えてしまっても想定通りの返り値を受け取っています。
引数の順番間違えはバグの中でも察知しにくいと思っていますのでこれはとてもありがたい機能ですね。

<?php

$toArray = function($title='タイトルが入ります', $detail='概要が入ります', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray(id:10, title:'title', detail:'detail'));
/*
想定通りの返り値になっている!
array(3) {
  ["id"]=>
  int(10)
  ["title"]=>
  string(5) "title"
  ["detail"]=>
  string(6) "detail"
}
*/
?>

任意のデフォルト値を持つ引数をスキップできるようになる

こちらも見出し通りですが、デフォルト値をもつ引数であればわざわざ記載する必要がなくなります。
下記の例では、 $id を指定したいがために $title  $detail にデフォルト値を渡しています。

<?php

$toArray = function($title='デフォルトのタイトル', $detail='デフォルトの概要文', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray('デフォルトのタイトル', 'デフォルトの概要文', 2));
/*
array(3) {
  ["id"]=>
  int(2)
  ["title"]=>
  string(30) "デフォルトのタイトル"
  ["detail"]=>
  string(27) "デフォルトの概要文"
}
*/
?>

名前付き関数を使って書き直すと下記のようになります。
変更したい引数のみの指定でよくなるのでコードがスッキリし、明示的にデフォルト値を使うことも見て取れます。

<?php

$toArray = function($title='デフォルトのタイトル', $detail='デフォルトの概要文', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray(id: 2));
/*
array(3) {
  ["id"]=>
  int(2)
  ["title"]=>
  string(30) "デフォルトのタイトル"
  ["detail"]=>
  string(27) "デフォルトの概要文"
}
*/
?>

エラーになるパターン

基本的なエラーになるパターンは下記の2通りです。
関数の引数を変更した際に引数がずれることなくエラーで止めてくれるようになるので、思わぬバグを引き起こしにくくなります。

引数にないパラメータを指定した場合

<?php

$toArray = function($title='デフォルトのタイトル', $detail='デフォルトの概要文', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray(noindex: 2)); // noindexというパラメータは存在しない
// PHP Fatal error:  Uncaught Error: Unknown named parameter $noindex in /path/to/code/test.php:line number
?>

同じパラメータを複数回指定した場合

<?php

$toArray = function($title='デフォルトのタイトル', $detail='デフォルトの概要文', $id=1) {
    return [
        'id' => $id,
        'title' => $title,
        'detail' => $detail,
    ];
};

var_dump($toArray(id: 2, id: 3)); // 引数$idを2回指定している
// PHP Fatal error:  Uncaught Error: Named parameter $id overwrites previous argument in /path/to/code/test.php:line number
?>

さいごに

ありそうで無かった機能「名前付き関数」についてまとめてきました。
PHP既存の関数でも利用可能なため、引数が複雑な htmlspecialchars() や場合によって引数の有無を変更したい array_column() など要所で使用することで、可読性の向上や、それに伴う改修・コードリーディングのコスト削減などメリットが多いと思います。
PHP8系以降の開発の際はぜひ使ってみてはいかがでしょうか。

この記事を書いた人

ばね
ばねソリューション事業部 システムエンジニア
東京で2年半エンジニアとしての経験を積み、浜松にUターンの後、アーティスへ入社。
ソリューション事業部のWebエンジニアとして、システムの設計・開発・保守・運用からインフラまで幅広く従事している。
フルスタックエンジニア目指して現在も勉強の日々。車が好き。
この記事のカテゴリ

FOLLOW US

最新の情報をお届けします