【サルが書く】PHP8のunion typesとmixedについて考える

2 min read読了の目安(約2200字

わあきゃあ!

PHP8がついにリリースされましたね!

そこで気になった新機能であるUnionTypesとmixed型についてまとめてみました。

1. UnionTypes

PHP8以前はプロパティ、パラメーター、および戻り値の型に対して単一の型しか宣言できませんでした。
またPHP7.1以降のバージョンではnull許容型があります。
PHP8以前は限定的なUnionTypesしかできませんでした。
ちなみにnull許容で書く場合は型の前に?をつけることでできます。 例) ?string

PHP8以前ではPHPDocを使用してのUnionTypesはありました。

class Test {  

 /**  
  * @var int|float  
  */  
  private $test;  

  /**  
   * @param int|float $foo
   * @return int|float  
   */  
  public function square(int $foo): int {  
    return $foo * $foo;  
  }
 }

PHP8ではこのように書けるってことですね!
この場合はPHPDocは書くべきなんですかね?
@param@returnの型についてのPHPDocはいらなくて、メソッドについての説明だけは残すって感じですかね?

class Test {  
  private int|float $test;
  public function square(int|float $foo): int|float {  
    return $foo * $foo;  
  }
 }

voidの扱いについて

voidはUnionTypesでは使用できません。
なので以下のような指定はできません。
strign|void

null許容型について

UnionTypesとnull許容型についてですが
?int|floatのようには書けず、int|float|nullのように書きます。

型の重複について

int|float|INT のように型は重複して書くことはできません。

false疑似型

falseリテラルの型が、UnionTypesの一部としてサポートされています。
これは内部関数の多くが、失敗時にnullではなくfalseを返すために実装されています。
またこれは単独で使用することはできません。
なので、false, ?false, false|nullのようなものは使用できません。

union型と型強制

strict_typesが有効でない場合、スカラー値は暗黙の型変換の対象となります。
例えば bool|intに対して"0"が渡ったときにはfalse0が暗黙の型変換の対象になります。
型変換の優先順位は以下のようになっているので、優先順位1のintへの型変換が働き"0"0へ変換されます。

型変換の優先順位
1.int 2.float 3.string 4.bool

2. mixed型

mixed型は以下のunion型と一緒です。
array|bool|callable|int|float|object|resource|string|null

最初こんな型があっても宣言しないのと同じじゃんとは考えていましたが、もちろん導入されたのには理由があります。
理由についてはこちらの記事 で詳しく書いてあるので、ユーザー目線からの意見をまとめました。

メリット

  • mixedと宣言することで、ここはすべての型が入りうるということを注意喚起できる
  • すべての場合で型宣言ができるので統一感のあるコードを書くことができる
  • 静的解析がやりやすくなる
  • 型指定へのハードルが下がる
  • リファクタリングの際にmixedをつければ検収済みだというマークになる

デメリット

  • あまり型宣言に精通していない人がコード書いた場合にTypeScriptのanyのように乱用される可能性がある

mixed型まとめ

メリットもデメリットもありますが、個人的にはmixed乱用はかなり有り得そうな話だと思っています。なので型宣言を適切に行えている前提かつ、miexdを乱用しなくても良い設計を心が得ける必要は出てきそうですね。

参考文献

https://www.php.net/manual/ja/language.types.declarations.php#language.types.declarations.union
https://php.watch/versions/8.0/union-types
https://speakerdeck.com/kawanamiyuu/phpkansai-2018-lt-mixed-typehint-dis?slide=20