In PHP, child classes can override class constants of their parents (unless they're marked as final
):
class A {
const FOO = [];
}
class B extends A {
const FOO = 'bar';
}
var_dump(A::FOO); // []
var_dump(B::FOO); // 'bar'
In PHP 8.3, class constants can be type hinted as well, in which case they follow a covariant behavior, allowing more specific/narrow types to be used in subclasses while disallowing broader/wider types.
In the following example, class B
extends class A
, and the type of the constant FOO
is narrowed to string|int
. Attempting to assign a float value (e.g. 1.0
) to it results in a fatal error:
// PHP 8.3+
class A
{
const string|int|float FOO = 'bar';
// ...
}
class B extends A
{
// Fatal error: Cannot use float as value for class constant `B::FOO` of type `string|int`
const string|int FOO = 1.0;
// ...
}
This demonstrates that class constant types can be made more narrow in subclasses, but not wider. If you attempt to make the type wider in a subclass, then it will result in an error:
// PHP 8.3+
class A
{
const string|int FOO = 'bar';
// ...
}
class B extends A
{
// Fatal error: Type of `B::FOO` must be compatible with `A::FOO` of type `string|int`
const string|int|float FOO = 1.0;
// ...
}
This post was published by Daniyal Hamid. Daniyal currently works as the Head of Engineering in Germany and has 20+ years of experience in software engineering, design and marketing. Please show your love and support by sharing this post.