Can Class Constants be Overridden in PHP?

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.