因為列舉成員在列舉本身上表示為常數,所以它們可以在大多數常數表達式中用作靜態值:屬性預設值、靜態變數預設值、參數預設值、全域和類別常數值。它們不能用於其他列舉成員值,但一般常數可以參考列舉成員。
然而,在靜態或常數定義中不允許對列舉型別進行隱式魔術方法呼叫,例如 ArrayAccess,因為我們無法絕對保證結果值是確定的,或者方法呼叫沒有副作用。在常數表達式中,函式呼叫、方法呼叫和屬性存取仍然是無效的操作。
<?php
// 這是一個完全合法的列舉型別定義。
enum Direction implements ArrayAccess
{
case Up;
case Down;
public function offsetExists($offset): bool
{
return false;
}
public function offsetGet($offset): mixed
{
return null;
}
public function offsetSet($offset, $value): void
{
throw new Exception();
}
public function offsetUnset($offset): void
{
throw new Exception();
}
}
class Foo
{
// 這是允許的。
const DOWN = Direction::Down;
// 這是被禁止的,因為它可能不是確定的。
const UP = Direction::Up['short'];
// 致命錯誤:常數表達式中不能對列舉型別使用 []
}
// 這完全合法,因為它不是常數表達式。
$x = Direction::Up['short'];
var_dump("\$x is " . var_export($x, true));
$foo = new Foo();
?>