型宣言~bool~
型宣言のbool編。どこまで許容されるのか検証。
Main.php
<?php function to_bool($val):bool { print "=== val=" . var_export($val, true) . " ===" . PHP_EOL; try { return $val; } catch (TypeError $e) { print $e->getMessage() . PHP_EOL; print $e->getTraceAsString() . PHP_EOL; return false; } } class Hoge { private int $val; public function __construct($val) { $this->val = $val; } } class MyInteger { private int $val; public function __construct($val) { $this->val = $val; } public function __toString():string { return $this->val; } } var_dump(to_bool(0)); var_dump(to_bool(00)); var_dump(to_bool(123)); var_dump(to_bool(0123)); var_dump(to_bool(0x123)); var_dump(to_bool(0.1)); var_dump(to_bool(1.23)); var_dump(to_bool(false)); var_dump(to_bool(true)); var_dump(to_bool("0")); var_dump(to_bool("00")); var_dump(to_bool("123")); var_dump(to_bool("0123")); var_dump(to_bool("0x123")); var_dump(to_bool("hello")); var_dump(to_bool("false")); var_dump(to_bool("true")); var_dump(to_bool(null)); var_dump(to_bool(new Hoge("123456789"))); var_dump(to_bool(new MyInteger("123456789")));
実行結果。
$ php81 Main.php === val=0 === bool(false) === val=0 === bool(false) === val=123 === bool(true) === val=83 === bool(true) === val=291 === bool(true) === val=0.1 === bool(true) === val=1.23 === bool(true) === val=false === bool(false) === val=true === bool(true) === val='0' === bool(false) === val='00' === bool(true) === val='123' === bool(true) === val='0123' === bool(true) === val='0x123' === bool(true) === val='hello' === bool(true) === val='false' === bool(true) === val='true' === bool(true) === val=NULL === to_bool(): Return value must be of type bool, null returned #0 /home/hhelibex/blog/2022-0703-01/Main.php(47): to_bool() #1 {main} bool(false) === val=Hoge::__set_state(array( 'val' => 123456789, )) === to_bool(): Return value must be of type bool, Hoge returned #0 /home/hhelibex/blog/2022-0703-01/Main.php(48): to_bool() #1 {main} bool(false) === val=MyInteger::__set_state(array( 'val' => 123456789, )) === to_bool(): Return value must be of type bool, MyInteger returned #0 /home/hhelibex/blog/2022-0703-01/Main.php(49): to_bool() #1 {main} bool(false) $
当然ながら、文字列 "false"、"true" はいずれも true となる。
ここで注意すべきなのは、あくまでも「:bool」であり「:boolean」とは書けないということ。 マニュアルに以下の記述がある。
警告 上記のスカラー型のエイリアスはサポートされていません。 つまり、これらはクラスやインターフェイスの名前として扱われているということです。 たとえば、型の宣言に boolean を使った場合、 値が boolean クラスまたはインターフェイスのインスタンスであることが要求されます。 bool 型ではありません。
もし「:boolean」と書いた場合、実行結果は以下のようになる。
PHP Warning: "boolean" will be interpreted as a class name. Did you mean "bool"? Write "\boolean" to suppress this warning in /home/hhelibex/blog/2022-0703-01/Main.php on line 3 === val=0 === to_bool(): Return value must be of type boolean, int returned #0 /home/hhelibex/blog/2022-0703-01/Main.php(30): to_bool() #1 {main} PHP Fatal error: Uncaught TypeError: to_bool(): Return value must be of type boolean, bool returned in /home/hhelibex/blog/2022-0703-01/Main.php:10 Stack trace: #0 /home/hhelibex/blog/2022-0703-01/Main.php(30): to_bool() #1 {main} thrown in /home/hhelibex/blog/2022-0703-01/Main.php on line 10