php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #75823 Proposal: Make a covariant types
Submitted: 2018-01-16 15:05 UTC Modified: 2018-01-16 17:48 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:1 (50.0%)
Same OS:1 (50.0%)
From: hack3p at gmail dot com Assigned: cmb (profile)
Status: Duplicate Package: Class/Object related
PHP Version: Irrelevant OS: irrelevant
Private report: No CVE-ID: None
 [2018-01-16 15:05 UTC] hack3p at gmail dot com
Description:
------------
The current invariative type interferes with writing idiomatic inheritance, which is implemented in many other languages. 

Now us have to completely remove the type of the return value and type and remove functions type hintings arguments in the parent and childs class, which helps to solve this. But in this case, in business logic now you need to manually implement type checking, since a secure application should work with the correct type. 

At the advent of PHP 7 with the possibility of strict typing, I hoped that the types will finally become variative. However, this did not happen. 

RFC by return types (https://wiki.php.net/rfc/return_types) in section "Variance and Signature Validation" has next: 
> This RFC originally proposed covariant return types but was changed to invariant because of a few issues. It is possible to add covariant return types at some point in the future. 

I think it's time to move towards idiomatic inheritance, since it will be correct if PHP to check the types, not the programmer.

Test script:
---------------
Test script: https://gist.github.com/hack3p/78eeca8f50d3297bf25768a9c72cafeb

Expected result:
----------------
Previous test script should be work

Actual result:
--------------
example 1: return type
PHP Fatal error:  Declaration of B::foo(): B must be compatible with A::foo(): A in ...

example 2: arguments type hinting
PHP Warning:  Declaration of B::foo(B $bar) should be compatible with A::foo(A $bar) in ...

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-01-16 16:23 UTC] rowan dot collins at gmail dot com
Hi, I recommend you have a look at the archives for the PHP-Internals mailing list, where most of the high-level decisions for the language are made. https://marc.info/?l=php-internals

This particular topic has come up a couple of times, most recently here: https://marc.info/?l=php-internals&m=151359959822329&w=2

In summary, the problem is that PHP's dynamic loading of classes leads to awkward edge cases where the compiler can't know whether a particular class follows correct covariance / contravariance rules until it has loaded other classes, which in turn might require loading other classes, or the original class. It's not insurmountable, but it's not trivial either.

Note that the simplest contravariance case of omitting a parameter constraint in a descendant class is now allowed in PHP 7.2.

Incidentally, your second example is incorrect: return types must be covariant (at least as specific as in the parent class) but parameter types must be contravariant (at least as tolerant as in the parent class).
 [2018-01-16 17:48 UTC] cmb@php.net
-Status: Open +Status: Duplicate -Package: PHP Language Specification +Package: Class/Object related -Assigned To: +Assigned To: cmb
 [2018-01-16 17:48 UTC] cmb@php.net
Duplicate of request #71825.
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Sep 17 09:01:26 2019 UTC