PHP 8: 名前付き引数 – Stitcher.io

in Vlog

(jp) =

ぎりぎりでしたが、PHP 8 では名前付き引数 (名前付きパラメーターとも呼ばれます) がサポートされています。 この投稿では、それらの詳細について説明しますが、最初に実際の例をいくつか示して、それらがどのように見えるかをお見せしましょう。

setcookie(
    name: 'test',
    expires: time() + 60 * 60 * 2,
);

組み込み PHP 関数で使用される名前付き引数

class CustomerData

    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) 


$data = new CustomerData(
    name: $input['name'],
    email: $input['email'],
    age: $input['age'],
);

プロモートされたプロパティと名前付き引数を使用する DTO

$data = new CustomerData(...$customerRequest->validated());

名前付き引数も配列展開をサポート

例から推測したかもしれません: 名前付き引数を使用すると、引数の順序ではなく引数名に基づいて、入力データを関数に渡すことができます。

名前付き引数は、私の日常のプログラミング生活に大きな影響を与える優れた機能だと思います。 あなたはおそらく詳細について疑問に思っているでしょう: 間違った名前を渡した場合、その配列展開構文はどうなっているでしょうか? それでは、これらすべての質問を詳しく見てみましょう。

# なぜ名前付き引数?

この機能が非常に議論されたものであり、それらを追加しないことに反論があったとしましょう. ただし、それらの利点は、下位互換性の問題や肥大化した API の懸念をはるかに上回っていると思います。 私の見方では、それらはよりクリーンで柔軟なコードを書くことを可能にします。

1 つは、名前付き引数を使用すると、デフォルト値をスキップできます。 Cookie の例をもう一度見てみましょう。

setcookie(
    name: 'test',
    expires: time() + 60 * 60 * 2,
);

そのメソッド シグネチャは、実際には次のとおりです。

setcookie ( 
    string $name, 
    string $value = "", 
    int $expires = 0, 
    string $path = "", 
    string $domain = "", 
    bool $secure = false, 
    bool $httponly = false,
) : bool

私が示した例では、Cookie を設定する必要はありませんでした。 $valueですが、有効期限を設定する必要がありました。 名前付き引数により、このメソッド呼び出しがもう少し簡潔になりました。

setcookie(
    'test',
    '',
    time() + 60 * 60 * 2,
);

setcookie 名前付き引数なし

setcookie(
    name: 'test',
    expires: time() + 60 * 60 * 2,
);

setcookie 名前付き引数付き

デフォルト値で引数をスキップすることに加えて、どの変数が何をするかを明確にするという利点もあります。 これは、メソッド シグネチャが大きい関数で特に役立ちます。 これで、多くの引数は通常、コードの匂いだと言えます。 何があってもそれらに対処しなければならないので、何もしないよりはまともな方法で対処する方がよいでしょう。

tpyoに気づきましたか? PR を送信して修正することができます。 このブログの最新情報を知りたい場合は、私をフォローしてください。 ツイッター または私のニュースレターを購読してください:

# 名前付き引数の詳細

基本的なことは終わったので、名前付き引数でできることとできないことを見てみましょう。

まず、名前付き引数は、名前のない (順序付きとも呼ばれる) 引数と組み合わせることができます。 その場合、順序付けられた引数は常に最初に来る必要があります。

前の DTO の例を見てみましょう。

class CustomerData

    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) 

次のように構築できます。

$data = new CustomerData(
    $input['name'],
    age: $input['age'],
    email: $input['email'],
);

ただし、名前付き引数の後に順序付き引数があると、エラーがスローされます。

$data = new CustomerData(
    age: $input['age'],
    $input['name'],
    email: $input['email'],
);

次に、名前付き引数と組み合わせて配列展開を使用することができます。

$input = [
    'age' => 25,
    'name' => 'Brent',
    'email' => '[email protected]',
];

$data = new CustomerData(...$input);

もしもただし、配列に必要なエントリがないか、名前付き引数としてリストされていないキーがある場合は、エラーがスローされます。

$input = [
    'age' => 25,
    'name' => 'Brent',
    'email' => '[email protected]',
    'unknownProperty' => 'This is not allowed',
];

$data = new CustomerData(...$input);

これ 入力配列で名前付き引数と順序付き引数を組み合わせることができますが、順序付き引数が以前と同じ規則に従う場合に限ります: それらは最初に来なければなりません!

$input = [
    'Brent',
    'age' => 25,
    'email' => '[email protected]',
];

$data = new CustomerData(...$input);


可変引数関数を使用している場合、名前付き引数はキー名とともに可変引数配列に渡されます。 次の例を見てください。

class CustomerData

    public static function new(...$args): self
    
        return new self(...$args);
    

    public function __construct(
        public string $name,
        public string $email,
        public int $age,
    ) 


$data = CustomerData::new(
    email: '[email protected]',
    age: 25,
    name: 'Brent',
);

この場合、 $argsCustomerData::new 次のデータが含まれます。

[
    'age' => 25,
    'email' => '[email protected]',
    'name' => 'Brent',
]

属性 (アノテーションとも呼ばれます) は、名前付き引数もサポートします。

class ProductSubscriber

    
    public function onProductCreated(ProductCreated $event)   

引数名として変数を持つことはできません:

$field = 'age';

$data = CustomerData::new(
    $field: 25,
);

最後に、名前付き引数は、継承中の名前の変更を実用的な方法で処理します。 次の例を見てください。

interface EventListener 
    public function on($event, $handler);


class MyListener implements EventListener

    public function on($myEvent, $myHandler)
    
        
    

PHP は、名前の変更を黙って許可します。 $event$myEvent、 と $handler$myHandler; しかし 親の名前を使用して名前付き引数を使用することにした場合、実行時エラーが発生します。

public function register(EventListener $listener)

    $listener->on(
        event: $this->event,
        handler: $this->handler, 
    );

場合の実行時エラー $listener のインスタンスです MyListener

この実用的なアプローチは、継承されたすべての引数が同じ名前を保持する必要がある場合に、重大な重大な変更を防ぐために選択されました。 私には良い解決策のようです。


名前付き引数について説明する必要があるのはこれだけです。 設計上の決定の背後にある裏話をもう少し知りたい場合は、RFC を読むことをお勧めします。

名前付き引数の使用を楽しみにしていますか? 経由でお知らせください ツイッター または電子メールで!

//platform.twitter.com/widgets.js

関連記事

前の投稿
ストリーミングするかスキップするか
次の投稿
Rufous Hornero: アルゼンチンの国鳥