Past discussions on the mailing lists have shed some light on the various ways we handle prototype checks and what may be done to improve PHP in that area. This RFC summarizes the current state (5.3/5.4) of prototype checks and possible improvements to it
Prototype checks occur in different contexts:
The prototype is checked with current normal rules (see Current rules). Any mismatch with current rules generates a FATAL error.
The prototype is checked with current normal rules (see Current rules). Any mismatch with current rules generates a FATAL error.
The prototype is checked with current normal rules (see Current rules). Any mismatch with current rules generates a STRICT error.
No checks are performed.
Scenario:
abstract class ParentAbs { abstract public function foo($a); } abstract class SubAbs extends ParentAbs { abstract public function foo($a); }
NOT allowed, always result in a fatal error even if the prototypes are compatible.
Scenario:
interface ParentIface { function foo($a); } interface SubIface extends ParentIface { function foo($a); }
NOT allowed, always result in a fatal error even if the prototypes are compatible.
This part specifies what is currently considered as valid signature modifications:
function foo($a)
is compatible with, in a sub class:
function foo($a, $b = 42)
function foo($a)
is compatible with, in a sub class:
function &foo($a)
This part specifies what is currently considered as invalid signature modifications:
Given:
class A {} class B extends A{}
function foo(A $a)
is imcompatible with, in a sub class:
function foo(B $a)
function &foo()
is imcompatible with, in a sub class:
function foo()
function foo()
is imcompatible with, in a sub class:
function foo($a)
This part specifies what is currently considered as invalid modifications, despite being theoretically sound:
function foo(Array $a)
is currently imcompatible with, in a sub class:
function foo($a)
Given:
class A {} class B extends A{}
function foo(B $a)
is currently imcompatible with, in a sub class:
function foo(A $a)
function foo(&$a)
is currently imcompatible with, in a sub class:
function foo($a)
function foo($a)
is currently imcompatible with, in a sub class:
function foo()
We have three wrong errors for modifications that should be accepted. Some of those might require more sophisticated checks than others, so not all might be worth including.
Constructors can be seen as pseudo-static methods, for this reason, the same checks for normal methods do not always apply for constructors.
It is however unclear whether we really want, for constructors, to be more strict (and how strict) if they are defined via an abstract class. So:
It would be better to allow multiple interfaces to define the same intersection of prototype. It is currently not allowed in any case.
For example:
interface A { function apply($a, $b); // ... } interface B { function apply($a, $b); // ... } class C implements A, B { .. }
This is currently not allowed, but there is no reason why it shouldn't be.