型宣言とunion型で「なんでも入る」をやめる
型宣言は引数や戻り値に期待する型を書く機能で、union型は複数の型のいずれかを許容します。実行時のガードとドキュメントを兼ね、想定外の値を宣言時点で見えるようにします。
PHPは型を書かなくても動きますが、書かないと「この引数に何が入るのか」が消えます。型宣言はドキュメントであり、実行時のガードでもあります。
引数・戻り値に型を付ける
function price(int $qty, float $unit): float
{
return $qty * $unit;
}
型が合わなければTypeErrorで即座に落ちます。「気づいたら文字列が混ざっていて計算がおかしい」を防げます。
union型で「複数あり得る」を表現
PHP 8のunion型は、複数の型のいずれかを許容します。
function find(int|string $id): ?User
{
// idは数値でも文字列でも受ける、戻りはUserかnull
}
戻り値の?UserはUser|nullの短縮形です。「見つからなければnull」を型で明示できます。
nullを混ぜるときの注意
「なんでもあり」にしたくてmixedを使いたくなる場面がありますが、これは型情報を捨てるのと同じです。本当に何でも来るのか、実はint|stringの2種だけなのか、を一度考えてみてください。union型で具体的に書けるなら、そのほうが後で読む人(自分含む)が助かります。
まとめ
型宣言はコストほぼゼロで得られる保険です。まず引数と戻り値に付ける、あり得る型が複数ならunion型で具体的に書く、mixedは最後の手段。これだけで、実行してみないと分からなかったバグの多くが宣言時点で見えるようになります。
よくある質問
Q. mixedとunion型はどう使い分けますか。
A. mixedは型情報を捨てるのと同じです。あり得る型がint|stringのように具体的に書けるなら、union型のほうが後で読む人に親切です。
Q. ?Userとはどういう意味ですか。
A. User|nullの短縮形で、「Userかnull」を表します。「見つからなければnull」を型で明示できます。