rfc:final_class_const

This is an old revision of the document!


PHP RFC: Final class constants

Introduction

Currently, class constants are always overridable by any child classes. This causes a few smaller caveats:

First of all, the engine can't optimize class constant references when late static binding is involved, so it has to pessimistically assume that FOO is overridden in case of static::FOO or $this::FOO invocations.

But more importantly, one cannot easily make sure whether an inherited class constant is overridable or not. For example let's consider the following code:

class Foo
{
    public const X = "foo";
 
    public function getX(): string
    {
        return self::X;
    }
}
 
class Bar extends Foo
{
    public const X = "bar";
 
    public function getBar(): string
    {
        return self::X;
    }
}

When overriding a class constant, one has to make sure that the parent class references class constants in an LSB context.

Proposal

The final modifier can be added to class constants. Doing so prevents a constant to be overridden in a child class:

class Foo
{
    final public const X = "foo";
}
 
class Bar extends Foo
{
    public const X = "bar";
}
 
// Fatal error: Bar::X cannot override final constant Foo::X

Besides, interface constants would become overridable by default:

interface I
{
    public const X = "i";
    final public const Y = "i";
}
 
class C implements I
{
    public const X = "c"; // Overriding I::X is not possible
    public const Y = "c"; // Overriding I::Y is not possible
}
 
// Fatal error: C::Y cannot override final constant I::Y

Reflection

A ReflectionClassConstant::isFinal()method is added in order to be able to retrieve if a constant is final.

Backward Incompatible Changes

None.

Vote

Add support for final class constants? The vote requires 2/3 majority to be accepted.

rfc/final_class_const.1619166924.txt.gz · Last modified: 2021/04/23 08:35 by kocsismate