I basically want an enum-like class in PHP. My enum should have a few values (they are all static). Let's say I want to have an enum that has an ID (the ID must never, ever change), and a name (the name must not change during runtime, it can change during compile-time -- e.g. from changes made to the code). The state must not have any side-effects (i.e. they are only getters and instance variables cannot be changed). A state must also not be created during runtime except when initializing the class.
For my concert example, I have three possible states: OPEN, CLOSED, and 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 { ... }
}
I want to refer to each state unambiguously in my code (MyState::STATE_OPEN, etc). This should also ensure that a compiler/linter/etc can verify that the state actually exists (there is no guarantee that getStateByID does not throw an exception). 
There are also some (de)serializers that can load a state after it has been saved (by using the never changing ID).
Unfortunately, I cannot set const or static instance variables if their object is from the same class. I get the following error:
Constant expression contains invalid operations
How can this be best accomplished in PHP? I know I can easily create an enum with just an int (class MyState { const STATE_OPEN = 1; }) but that has a major disadvantage: the enum is not an object and thus cannot have methods. I cannot use type hinting this way and I might pass an invalid enum. E.g., function takeMyState(int $state) can actually use an enum that has never been defined.
 
    