HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

型宣言~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