【PHP/Laravel】enum backing type must be int or string

php-laravel

状況

  • error:「enum backing type must be int or string, bool given
  • enumにboolを当ててエラー。

Enumerations(列挙型)

  • そもそも「enum」は、複数の定数をenumして、独自の型を制御できる。
  • phpの場合、8.1以降。
  • enum backing type(Backed Enum)とあるように、pure enumもある。
  • 今回のエラーはBacked Enumの場合。enumのデフォルトは、pure enum。これはスカラー値を持っていないこと(シングルトンオブジェクト)を言う。つまり、スカラー値を定義した場合、Backed Enum。このBacked Enumは、「int、string」を持つことが出来る。つまり、boolは使えない。よって、「enum backing type must be int or string, bool given」となった。冒頭の状況はこれに当たるので、型を変更して問題解決。
  • また、intも使ってstringも使うといったunion 型はサポートしてないので、両方使うとエラーになる。
  • Backed Enumのスカラー値はユニークで、明示しなくてはいけない。別名は作成できる。また、スカラー値はリテラルか、リテラルを表す式でなければならない。つまり、’hoge’、1 + 1といった形(1 + CONSTはエラーになる)。
  • Backed Enumのcaseは読み取り専用のvalue、nameのプロパティを持ってる。例えば、var_dump(Test::case1->value; とかTest::case1->name;みたいな要領で。これは読み取り専用のため、リファレンスを変数に代入は不可能。cf) 「リファレンスを返す
  • 列挙型そのものはクラスで、enumで定義されるcaseはインスタンスに当たる。では、クラスとenumの違いは何だろうか? cf) 「PHP 8.1 Enums を使ってみる」
  • 列挙型は、名前空間をサポートしてる。例えば、namespace App\Services;でenum Testを使用し、それをcontrollerでuseする場合、App\Services\Test。そのまま定義した定数を使用できる。継承は不可。
  • enumにはメソッドを含めることも出来る。pure enumでintとstringを分けることも出来るし、Backed Enumでスカラー値を定義して、classで使用することも可能。予め定数が決まっているのならBacked Enumを使うし、柔軟に変更したいならpure enumで各々メソッドで決めても良い。
<?php

enum Hoge
{
    case A10;
    case B100;
    case C1000;
    case OK;
    case NG;
    case TEST;
    public function number(): int
    {
        return match($this) {
            Hoge::A10 => 10,
            Hoge::B100 => 100,
            Hoge::C1000 => 1000
        };
    }
    public function string(): string
    {
        return match($this) {
            Hoge::OK => "a",
            Hoge::NG => "b",
            Hoge::TEST => "c"
        };
    }
}

enum Sample :int
{
    case aaa1 = 1;
    case bbb2 = 2;
    case ccc3 = 3;
}

class Test {
    public function test(){
        return Hoge::B100->number();
    }
    public function test2(){
        return Sample::bbb2->value;
    }
}

$t = new Test;
var_dump($t->test());//int(100)
var_dump($t->test2());//int(2)


$a = Hoge::A10;
$b = Hoge::B100;
var_dump($a->number()); //int(10)
var_dump($b->number()); //int(1000);

$c = Hoge::OK;
$d = Hoge::TEST;
var_dump($c->string()); //string(1) "a"
var_dump($d->string()); //string(1) "c"
?>

参照

列挙型(Enum)
値に依存した列挙型(Backed Enum)
ReflectionProperty::getValue
PHP 8.1: Enums

Laravel, php, programming

Posted by 異世界攻略班