Table of Contents

PHP RFC: Extend #[\Override] to target properties

Introduction

This is a follow-up to a previous RFC which introduced the #[\Override] attribute to explicitly express the intent of a method to override a parent method or implement an interface. During inheritance, PHP then checks that the method actually exists in the parent hierarchy or in one of the implemented interfaces.

The original RFC explicitly excluded properties:

As of now properties may not be part of an interface and thus only properties of a parent class can be overridden. The type of properties is enforced to be invariant and properties do not have behavior attached. A property can only ever be overridden by a compatible property with possibly added attributes.

A lot has changed in PHP 8.4 and, as a result, some of these premises are no longer true:

Overall, these changes have allowed properties to become a more prominent part of the public API of a class or an interface, and I think it warrants the original decision to be revisited.

Proposal

I propose to extend the target of the #[\Override] attribute to include properties. If this attribute is added to a property, the engine validates that a property with the same name exists in a parent class or any of the implemented interfaces and emits a compilation error if no such property exists.

The semantics are the same as with methods:

Examples

class P {
    abstract public mixed $p { get; }
}
 
class C extends P {
    #[\Override]
    public mixed $p;
}
trait T {
    #[\Override]
    public mixed $p;
}
 
interface I {
    public mixed $p { get; }
}
 
class C implements I {
    use T;
}
class C {
    #[\Override]
    public mixed $c; // Fatal error: C::$c has #[\Override] attribute, but no matching parent property exists
}
interface I {
    #[\Override]
    public mixed $i; // Fatal error: I::$i has #[\Override] attribute, but no matching parent property exists
}
interface I {
    public mixed $i { get; }
}
 
class P {
    #[\Override]
    public mixed $i; // Fatal error: P::$i has #[\Override] attribute, but no matching parent property exists
}
 
class C extends P implements I {}
class P {
    private mixed $p;
}
 
class C extends P {
    #[\Override]
    public mixed $p; // Fatal error: C::$p has #[\Override] attribute, but no matching parent property exists
}

Precedent in other programming languages

Backward Incompatible Changes

None.

Proposed PHP Version(s)

Next minor (8.5)

RFC Impact

To the Ecosystem

IDEs and static analyzers will likely want to extend their rules for #[\Override] to properties.

To Existing Extensions

Extensions might want to add the attribute to their properties where appropriate.

To SAPIs

None.

Voting Choices

Extend #[\Override] to target properties?
Real name Yes No
Final result: 0 0
This poll has been closed.

Patches and Tests

Implementation

After the RFC is implemented, this section should contain:

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature

References

Rejected Features

Keep this updated with features that were discussed on the mail lists.

Changelog

If there are major changes to the initial proposal, please include a short summary with a date or a link to the mailing list announcement here, as not everyone has access to the wikis' version history.