PHP RFC: Always generate fatal error for incompatible method signatures
- Date: 2019-04-08
- Author: Nikita Popov nikic@php.net
- Status: Implemented
- Target Version: PHP 8.0
- Implementation: https://github.com/php/php-src/pull/4000
Introduction
Inheritance errors due to incompatible method signatures (LSP violations) currently either throw a fatal error or a warning depending on the cause of the error and the inheritance hierarchy. This RFC proposes to always throw a fatal error in PHP 8.
The following code currently generates a fatal error, because the signature of C::method()
is
incompatible with I::method()
.
interface I { public function method(array $a); } class C implements I { public function method(int $a) {} } // Fatal error: Declaration of C::method(int $a) must be compatible with I::method(array $a)
However, the following code only generates a warning:
class C1 { public function method(array $a) {} } class C2 extends C1 { public function method(int $a) {} } // Warning: Declaration of C2::method(int $a) should be compatible with C1::method(array $a)
The difference between these two examples is that I::method()
comes from an interface, while
C1::method()
comes from a class. More generally, a fatal error is thrown if an abstract method
(possibly coming from an interface) of the same name occurrs anywhere higher in the inheritance
hierarchy.
As an exception to this rule, signature errors caused by return types always result in a fatal error:
class C1 { public function method($a): array {} } class C2 extends C1 { public function method($a): int {} } // Fatal error: Declaration of C2::method($a): int must be compatible with C1::method($a): array
In PHP 5.0 the method signature check for non-abstract methods generated a strict standards notice. It was elevated to a warning in PHP 7.0. Because it was understood that this will be upgraded to a fatal error in the future, the newly introduced return type functionality opted to to throw a fatal error right away.
Proposal
Always throw a fatal error on incompatible method signatures, regardless of cause or origin. The rules of what constitutes a compatible signature are not changed.
Backward Incompatible Changes
Code intentionally using incompatible method signatures and suppressing the generated warning may break.
Vote
Voting started 2019-04-23 and ends 2019-05-07.