PHPの名前付き引数の使い方について

採用はこちら

PHPの名前付き引数とは、関数やメソッドを呼び出す際に、引数の順番ではなく「引数名」を指定して値を渡す機能です。

PHP 8.0から利用できるようになった機能で、引数が多い関数や、一部のオプション引数だけを指定したい場合に役立ちます。

通常の位置指定引数では、関数定義の順番に従って値を渡します。

function createUser($name, $age, $country)
{
    echo "{$name} / {$age} / {$country}";
}

createUser('Taro', 30, 'Japan');

一方、名前付き引数では次のように記述できます。

createUser(
    name: 'Taro',
    age: 30,
    country: 'Japan'
);

name:age:のように、パラメータ名の後ろにコロン:を付けて値を指定するのが基本です。

目次

PHPで名前付き引数を使う基本的な方法

引数名を指定して値を渡す

名前付き引数では、関数で定義されているパラメータ名を指定して値を渡します。

function greet($name, $message)
{
    echo "{$message}, {$name}!";
}

greet(
    name: 'Taro',
    message: 'Hello'
);

実行結果は次のようになります。

Hello, Taro!

通常の位置指定引数では、次のように書きます。

greet('Taro', 'Hello');

どちらも同じ結果になりますが、名前付き引数を使うと、各値が何を意味しているのかコード上で分かりやすくなります。

名前付き引数は順番を変更できる

名前付き引数では、パラメータ名を正しく指定していれば、関数定義と同じ順番で記述する必要はありません。

function createUser($name, $age, $country)
{
    echo "{$name} / {$age} / {$country}";
}

createUser(
    country: 'Japan',
    name: 'Taro',
    age: 30
);

この場合でも、PHPはパラメータ名を基準に値を割り当てるため、正しく実行されます。

Taro / 30 / Japan

引数の順番を覚える必要が少なくなるため、引数の多い関数では特に便利です。

デフォルト引数と名前付き引数を組み合わせる方法

途中のオプション引数を省略できる

名前付き引数の大きなメリットのひとつが、デフォルト値を持つ途中の引数を省略できることです。

例えば、次の関数があるとします。

function createAccount(
    $name,
    $age = 20,
    $country = 'Japan',
    $active = true
) {
    // 処理
}

$nameだけを指定する場合は、次のように呼び出せます。

createAccount(name: 'Taro');

さらに、$countryだけデフォルト値から変更したい場合は、次のように記述できます。

createAccount(
    name: 'Taro',
    country: 'USA'
);

この場合、それぞれの値は次のようになります。

name    = Taro
age     = 20
country = USA
active  = true

位置指定引数だけでは、後ろの引数を指定するために途中の値も記述しなければならない場合があります。

名前付き引数を使えば、必要なオプションだけを指定できます。

位置指定引数と名前付き引数を併用する方法

位置指定引数を先に書く

PHPでは、位置指定引数と名前付き引数を組み合わせることもできます。

function createUser($name, $age = 20, $country = 'Japan')
{
    // 処理
}

createUser(
    'Taro',
    country: 'USA'
);

この場合、'Taro'は最初の$nameに入り、$countryには'USA'が設定されます。

$ageにはデフォルト値の20が使用されます。

名前付き引数の後に位置指定引数は書けない

位置指定引数と名前付き引数を併用する場合、位置指定引数を先に記述する必要があります。

次の書き方はできません。

createUser(
    name: 'Taro',
    30
);

名前付き引数を記述した後に位置指定引数を置くことはできないためです。

基本的には、次の順番で記述します。

位置指定引数 → 名前付き引数

例えば、次の形であれば問題ありません。

createUser(
    'Taro',
    country: 'USA'
);

名前付き引数ではパラメータ名を正確に指定する

関数定義に存在する名前を使う

名前付き引数では、関数やメソッドに定義されているパラメータ名を正確に指定する必要があります。

例えば、次の関数があります。

function greet($name)
{
    echo "Hello {$name}";
}

正しい呼び出し方は次のとおりです。

greet(name: 'Taro');

一方、次のように存在しないパラメータ名を指定することはできません。

greet(username: 'Taro');

$usernameというパラメータは定義されていないため、Unknown named parameterに関するエラーが発生します。

大文字・小文字やスペルにも注意する

名前付き引数では、実際に定義されているパラメータ名をそのまま使用することが重要です。

特にPHPの組み込み関数を利用する場合は、公式ドキュメントやIDEの補完機能でパラメータ名を確認すると安全です。

同じ引数を重複して指定することはできない

位置指定と名前指定で同じ引数を渡さない

すでに位置指定引数で値を渡したパラメータを、名前付き引数でもう一度指定することはできません。

function test($name, $age)
{
    // 処理
}

test(
    'Taro',
    name: 'Jiro'
);

このコードでは、'Taro'がすでに$nameに割り当てられています。

その後にname: 'Jiro'を指定しているため、同じ引数を重複して渡すことになり、エラーになります。

クラスのメソッドで名前付き引数を使う方法

通常のメソッドでも利用できる

名前付き引数は、通常の関数だけでなくクラスのメソッドでも使用できます。

class User
{
    public function create($name, $age = 20, $active = true)
    {
        echo "{$name} / {$age}";
    }
}

$user = new User();

$user->create(
    name: 'Taro',
    active: false
);

この場合、$ageにはデフォルト値の20が入り、$activeにはfalseが設定されます。

オプション引数の多いメソッドでは、特に分かりやすい書き方です。

コンストラクタで名前付き引数を使う方法

オブジェクト生成時にも利用できる

名前付き引数は、クラスのコンストラクタでも使用できます。

class User
{
    public function __construct(
        public string $name,
        public int $age = 20,
        public string $country = 'Japan'
    ) {
    }
}

$user = new User(
    name: 'Taro',
    country: 'USA'
);

この場合、各プロパティには次の値が設定されます。

name    = Taro
age     = 20
country = USA

PHP 8以降のコンストラクタプロパティプロモーションと組み合わせることで、簡潔に記述できます。

PHPの組み込み関数で名前付き引数を使う方法

array_slice()で途中の引数を省略する

PHPの組み込み関数でも名前付き引数を使用できます。

例えば、array_slice()には複数のパラメータがあります。

$data = ['a', 'b', 'c', 'd'];

$result = array_slice(
    array: $data,
    offset: 1,
    preserve_keys: true
);

この書き方では、lengthを省略しながらpreserve_keysだけを指定できます。

これは名前付き引数のメリットが分かりやすい例です。

組み込み関数ではパラメータ名を確認する

名前付き引数ではパラメータ名が重要になるため、組み込み関数を使用する場合は、使用しているPHPバージョンの公式ドキュメントを確認することをおすすめします。

位置指定引数であれば引数名を意識する必要はありませんが、名前付き引数ではパラメータ名そのものが呼び出しコードに影響します。

配列を展開して名前付き引数を渡す方法

文字列キーの配列をアンパックする

PHP 8以降では、文字列キーを持つ配列を...で展開し、名前付き引数として渡すことができます。

function createUser($name, $age, $country)
{
    echo "{$name} / {$age} / {$country}";
}

$params = [
    'name' => 'Taro',
    'age' => 30,
    'country' => 'Japan',
];

createUser(...$params);

文字列キーのnameagecountryが、それぞれ対応するパラメータ名として扱われます。

設定値を配列として管理している場合に便利な方法です。

配列のキー名とパラメータ名を一致させる

名前付き引数として配列を展開する場合も、キー名と関数側のパラメータ名が一致している必要があります。

例えば、

$params = [
    'username' => 'Taro',
];

という配列を、

function greet($name)
{
}

に渡しても、usernameに対応するパラメータが存在しないため、そのままでは正常に処理できません。

可変長引数と名前付き引数を組み合わせる方法

未処理の名前付き引数を可変長引数で受け取れる

PHPでは、可変長引数を利用して名前付き引数を受け取ることもできます。

function test(...$args)
{
    var_dump($args);
}

test(
    name: 'Taro',
    age: 30
);

この場合、$argsには概念的に次のような内容が入ります。

[
    'name' => 'Taro',
    'age' => 30,
]

文字列キーを保持した状態で受け取れるため、柔軟なAPIを作成する際に利用できます。

ただし、初心者向けのコードでは必要性が低いことも多いため、応用的な使い方として覚えておくとよいでしょう。

PHPの名前付き引数を使うメリット

引数の意味が分かりやすくなる

次のコードでは、それぞれの値が何を意味しているのか分かりにくい場合があります。

createUser('Taro', 30, true, false);

名前付き引数を使うと、次のように意味を明確にできます。

createUser(
    name: 'Taro',
    age: 30,
    active: true,
    admin: false
);

特にtruefalse、数値が複数並ぶ場合は、可読性の向上につながります。

不要なnullを省略できる

例えば、次のような関数があるとします。

function sendMail(
    $to,
    $subject,
    $body,
    $cc = null,
    $bcc = null,
    $html = false
) {
}

位置指定引数だけで$htmltrueにする場合は、次のように途中の値を指定する必要があります。

sendMail(
    'user@example.com',
    'Hello',
    'Message',
    null,
    null,
    true
);

名前付き引数を使えば、次のように簡潔に記述できます。

sendMail(
    to: 'user@example.com',
    subject: 'Hello',
    body: 'Message',
    html: true
);

不要なnullを並べずに済むため、コードの意図が明確になります。

コードの可読性を高めやすい

例えば、次のようなコードがあります。

connect(
    host: 'localhost',
    port: 3306,
    timeout: 10,
    persistent: false
);

どの値が何を表しているか一目で分かるため、引数の多い処理ほど名前付き引数の効果が大きくなります。

PHPの名前付き引数を使う際の注意点

パラメータ名の変更が後方互換性に影響する

名前付き引数を使用すると、呼び出し側がパラメータ名に依存するようになります。

例えば、次の関数があります。

function greet($name)
{
}

呼び出し側が次のようになっているとします。

greet(name: 'Taro');

その後、関数定義を次のように変更した場合です。

function greet($username)
{
}

位置指定引数で、

greet('Taro');

と呼び出しているコードであれば影響を受けません。

しかし、

greet(name: 'Taro');

という呼び出しでは、nameというパラメータが存在しなくなるため正常に動作しません。

そのため、ライブラリや公開APIでは、パラメータ名の変更が実質的な後方互換性に影響する可能性があります。

PHP 8.0未満では使用できない

名前付き引数はPHP 8.0から導入された機能です。

そのため、PHP 7.x以前の環境では使用できません。

古いPHPバージョンもサポートする必要がある場合は、従来の位置指定引数を使用する必要があります。

必須引数とオプション引数の定義順にも注意する

関数を設計する場合は、基本的に必須引数を先に、デフォルト値を持つオプション引数を後ろに定義するのが適切です。

function example(
    $required,
    $optional = 'default'
) {
}

一方、次のような定義は避けた方がよいでしょう。

function example(
    $optional = 'default',
    $required
) {
}

PHP 8.1以降では、オプション引数の後ろに必須引数を定義する形式は、前方の引数を実質的に必須として扱うケースがあり、期待した省略ができなくなります。

名前付き引数を使う場合でも、関数自体のパラメータ設計を適切に行うことが重要です。

名前付き引数を多用しすぎる必要はない

名前付き引数は便利ですが、すべての関数呼び出しで使用する必要はありません。

例えば、引数が少なく意味が明確な関数であれば、位置指定引数の方が簡潔です。

max(10, 20);

このような処理まで無理に名前付き引数へ変更する必要はありません。

引数の意味が分かりにくい場合や、途中のオプション引数を省略したい場合に使うのが効果的です。

PHPの名前付き引数が向いているケース

引数が多い関数やメソッド

引数が多くなるほど、それぞれの値が何を意味しているのか分かりにくくなります。

createThumbnail(
    width: 800,
    height: 600,
    crop: true,
    quality: 90
);

名前付き引数にすれば、コードだけで設定内容を把握しやすくなります。

デフォルト引数が多い処理

後ろのオプションだけ変更したい場合にも適しています。

例えば、

sendMail(
    to: 'user@example.com',
    subject: 'Hello',
    body: 'Message',
    html: true
);

のように、途中のオプションを省略できます。

trueやfalseを複数渡す処理

次のようなコードは意味を判断しにくい場合があります。

configure(true, false, true);

名前付き引数なら、次のように意図を明確にできます。

configure(
    cache: true,
    debug: false,
    logging: true
);

可読性を重視する場合に有効です。

PHPの名前付き引数を使って読みやすいコードを書こう

PHPの名前付き引数は、PHP 8.0から利用できる機能です。

基本的な書き方は次のとおりです。

functionName(
    argumentName: value
);

名前付き引数を使うことで、引数の意味を明示したり、引数の順番を変更したり、途中のデフォルト引数を省略したりできます。

特に、引数が多い関数やメソッド、truefalseが複数並ぶ処理、オプション設定が多い処理では、コードの可読性を高めやすくなります。

一方で、名前付き引数はパラメータ名に依存するため、関数やライブラリ側でパラメータ名を変更すると、既存コードの互換性に影響する可能性があります。

PHPの名前付き引数は、すべての場面で使うのではなく、「引数の意味を明確にしたい場合」や「途中のオプション引数を省略したい場合」に活用するのが効果的です。

以上、PHPの名前付き引数の使い方についてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次