> 'Order does not match OrderForCheckout. Reason: ...'. Sorry, this is text for second example) I missed this moment. But I think the idea is clear.
For manual call of __match() type casting can be used: $orderForCheckout = (OrderForCheckout)$order; Also this feature can be used for checking enum values or intervals. class Value { public $value; public function __construct($value) { $this->value = $value; } } class State variant of Value { const ACTIVE = 1; const INACTIVE = 2; public function __match() { return in_array($this->value, [self::ACTIVE, self::INACTIVE]); } } function setState(State $s) { ... } setState(new State(3)); In constructions like "new State($value)" __match() can be called after __construct(). If to add a possibility to use data types, class Value will not be needed: class State variant of integer { ... public function __match() { return in_array($this, [self::ACTIVE, self::INACTIVE]); } } setState(3);