This is an old revision of the document!
PHP RFC: Parameter No Type Variance
- Version: 0.2
- Date: 2017-01-01
- Author: Niklas Keller me@kelunik.com
- Status: Under Discussion
- First Published at: http://wiki.php.net/rfc/parameter-no-type-variance
Introduction
PHP doesn't currently allow variance for parameters as checking these for compatibility isn't possible on compile time. This limitation is caused by autoloading and doesn't allow widening the accepted parameters.
Proposal
This RFC proposes to allow omitting the type entirely in a subclass, as dropping all parameter constraints is always valid according to the LSP principle.
Another practical use-case is, instead of widening the accepted type, allowing parent classes to introduce type declarations and having the sub-classes still compatible, i.e. this allows libraries to be upgraded to use (scalar) type declarations instead of manual checks without requiring an update for all sub-classes.
Example 1
<?php class ArrayClass { public function foo(array $foo) { /* ... */ } } class IterableClass extends ArrayClass { // This implementation also accepts Traversable. // Variance is already possible in this special case using "iterable". public function foo(iterable $foo) { /* ... */ } } class EverythingClass extends ArrayClass { // This implementation accepts all values. // Restrictions may be done via user code in the method body. // Variance is currently not allowed, it throws a warning if parent or child miss a type. public function foo($foo) { /* ... */ } }
Current Result
Warning: Declaration of EverythingClass::foo($foo) should be compatible with ArrayClass::foo(array $foo) in %s on line 18
Proposed Result
Compiles without a warning.
Example 2
Derick added a DateTimeZone
type declaration for the third arg of the DateTime::createFromFormat()
method. The method is already documented to accept only this class in the manual, but the type declaration is not actually present in the implementation.
However, this change had to be reverted, because all classes extending DateTime
currently don't have this type declaration (and adding it would be illegal under LSP), so they started throwing a method signature mismatch warning.
Backward Incompatible Changes
None.
Proposed PHP Version(s)
Next version, currently 7.2.
Future Scope
In the future there might be full support for contra-variance / co-variance for parameters / return types.
Proposed Voting Choices
Requires a 2/3 majority.
Patches and Tests
TBD.
Implementation
TBD.
References
None.