関数の引数に...
を使うことができるようで、どういう使い方ができるのかよくわかっていなかったので調べた。
バージョン
PHP5.6以降。*1
以下の実行環境は PHP 7.3.7
。
関数の引数
3点リーダを使うケースには2パターンある。
可変長引数
引数のアンパック
可変長引数
関数の定義時に3点リーダを使うと、引数を配列に入れてくれる。
<?php function myFunc (...$args) { var_dump($args); } $args = [1,2,3]; myFunc($args); # array(1) { [0]=> array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) } } myFunc(1, 2, 3); # array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }
引数のアンパック
逆に、呼び出し時に3点リーダを使うと、配列を展開してくれる。
<?php function myFunc2($a, $b, $c) { echo "$a / $b / $c"; } $args = [1, 2, 3]; myFunc2(...$args); # 1 / 2 / 3
アンパックとタイプヒンティング
タイプヒンティングもできる。 ただ、定義時に型指定バッチリしておいて、呼び出し側を配列にするメリットが今の所思い浮かばない。
<?php class Name { private $true_name; public $false_name; public function __construct(string $oracle) { $this->true_name = $oracle; $this->false_name = sha1($oracle); } public function __toString() { return $this->false_name; } } class Persona { private $persona; public function __construct(...$elements) { $this->persona = $elements; } public function express() { return implode(',', $this->persona); } } class Truth { private $idea; public function __construct(string $idea) { $this->idea = $idea; } public function express() { return ''; } } class Subject { private $name; private $persona; public function __construct(Name $name, Persona $persona) { $this->name = $name; $this->persona = $persona; } public function selfIntroduction() { echo "Hey, i'm $this->name. my property is expressed by " . $this->persona->express(); } } $name = new Name('Anderiens'); $persona = new Persona('male', 'engineer', 'smart'); $truth = new Truth('Cogito, ergo sum.');
とクラス定義をした上で、
<?php $anderiens1 = new Subject(...[$name, $persona]); $anderiens2 = new Subject(...[$persona, $name]); $anderiens3 = new Subject(...[$name, $truth]); $anderiens1->selfIntroduction(); // Hey, i'm 9f2ee80b1cc40f738b0acb6305070f994be4dee0. my property is expressed by male,engineer,smart $anderiens2->selfIntroduction(); // PHP Fatal error: Uncaught TypeError: Argument 1 passed to Subject::__construct() must be an instance of Name $anderiens3->selfIntroduction(); // PHP Fatal error: Uncaught TypeError: Argument 2 passed to Subject::__construct() must be an instance of Persona
付録
PHP7.4以降だと、さらに配列のアンパック機能が追加になるとのこと。