rfc:lsp_errors

PHP RFC: Always generate fatal error for incompatible method signatures

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.

Always generate fatal error for incompatible method signatures in PHP 8?
Real name Yes No
andrey (andrey)  
ashnazg (ashnazg)  
bishop (bishop)  
carusogabriel (carusogabriel)  
cmb (cmb)  
cpriest (cpriest)  
danack (danack)  
derick (derick)  
didou (didou)  
diegopires (diegopires)  
duncan3dc (duncan3dc)  
emir (emir)  
galvao (galvao)  
gasolwu (gasolwu)  
girgias (girgias)  
guilhermeblanco (guilhermeblanco)  
jhdxr (jhdxr)  
kalle (kalle)  
kguest (kguest)  
kinncj (kinncj)  
malukenho (malukenho)  
marcio (marcio)  
mariano (mariano)  
mcmic (mcmic)  
nikic (nikic)  
ocramius (ocramius)  
pajoye (pajoye)  
patrickallaert (patrickallaert)  
peehaa (peehaa)  
petk (petk)  
pmjones (pmjones)  
pmmaga (pmmaga)  
pollita (pollita)  
reywob (reywob)  
salathe (salathe)  
santiagolizardo (santiagolizardo)  
sebastian (sebastian)  
sergey (sergey)  
stas (stas)  
trowski (trowski)  
weierophinney (weierophinney)  
yunosh (yunosh)  
Final result: 39 3
This poll has been closed.
rfc/lsp_errors.txt · Last modified: 2019/05/07 08:32 by nikic