PHP:值为

时间:2016-11-11 03:48:24

标签: php enums

我基本上想在PHP中使用类似枚举的类。我的枚举应该有一些值(它们都是静态的)。假设我想要一个具有ID的枚举(ID必须永远不会改变)和一个名称(名称在运行时不得更改,它可以在编译期间更改 - 例如,对代码所做的更改)。国家不得有任何副作用(即它们只是吸气剂,实例变量不能改变)。除了初始化类之外,还必须在运行时期间不创建状态。

对于我的音乐会示例,我有三种可能的状态:OPEN,CLOSED和UNKOWN:

class MyState {
    const STATE_OPEN = new MyState(1, "open");
    const STATE_CLOSE = new MyState(2, "closed");
    const STATE_UNKOWN = new MyState(3, "unkown");

    private $name;
    private $state;

    private function __construct(int $state, string $name) {
        $this->state = $state;
        $this->name = $name;
    }

    public function getName() : string {
        return $this->name;
    }

    public function getState() : int {
        return $this->state;
    }

    public function getStateByID(int $state) : MyState { ... }
    public function getStateByName(string $name) : MyState { ... }
}

我想在我的代码中明确地引用每个状态(MyState :: STATE_OPEN等)。这还应该确保编译器/ linter / etc可以验证状态实际存在(不能保证getStateByID不会抛出异常)。

还有一些(de)序列化程序可以在保存之后加载状态(通过使用永不更改的ID)。

不幸的是,如果对象来自同一个类,我就无法设置const或静态实例变量。我收到以下错误:

Constant expression contains invalid operations

如何才能在PHP中实现这一目标?我知道我可以轻松地创建一个只有int(class MyState { const STATE_OPEN = 1; })的枚举,但它有一个主要的缺点:枚举不是一个对象,因此不能有方法。我不能以这种方式使用类型提示,我可能会传递无效的枚举。例如,function takeMyState(int $state)实际上可以使用从未定义过的枚举。

1 个答案:

答案 0 :(得分:1)

替换您的常量行

  const STATE_OPEN = new MyState(1, "open");

通过公共职能:

  public function STATE_OPEN() { return new MyState(1, "open"); }

产生这样的示例程序:

class MyState {
  public function STATE_OPEN() { return new MyState(1, "open"); }
  public function STATE_CLOSED() { return new MyState(2, "closed"); }
  public function STATE_UNKNOWN() { return new MyState(3, "unknown"); }

  private $name;
  private $state;

  private function __construct(int $state, string $name) {
    $this->state = $state;
    $this->name = $name;
  }

  public function getName() : string {
    return $this->name;
  }

  public function getState() : int {
    return $this->state;
  }
}

$state = MyState::STATE_CLOSED();

echo $state->getName() . "(" . $state->getState() . ")\n";