Doc->Bug #81038 [Nab->Opn]: the variance and traits
| From: | cmb@php.net | Date: | Mon, 17 May 2021 13:13:13 +0000 |
| Subject: | Doc->Bug #81038 [Nab->Opn]: the variance and traits | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-233867@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=81038&edit=1
ID: 81038
Updated by: cmb@php.net
Reported by: sh-ya at ya dot ru
Summary: the variance and traits
-Status: Not a bug
+Status: Open
-Type: Documentation Problem
+Type: Bug
-Package: Documentation problem
+Package: Scripting Engine problem
PHP Version: 7.4.19
-Assigned To: cmb
+Assigned To:
Block user comment: N
Private report: N
New Comment:
Maybe there is actually a bug, but I don't think it will be fixed.
Previous Comments:
------------------------------------------------------------------------
[2021-05-17 12:58:18] sh-ya at ya dot ru
comment out "use SomeTrait" and that order will work
------------------------------------------------------------------------
[2021-05-17 10:43:30] cmb@php.net
The problem is the order of the definitions. Animal cannot be
resolved until AnimalFood is defined, and that trips up the
script. This is basically documented[1]:
| Unless autoloading is used, the classes must be defined before
| they are used. If a class extends another, then the parent class
| must be declared before the child class structure. This rule
| applies to classes that inherit other classes and interfaces.
So yes, the best solution is to use autoloading; alternatively you
can fix the order of definitions[2] (that may not always be
possible).
[1] <https://www.php.net/manual/en/language.oop5.inheritance.php>
[2] <https://3v4l.org/RsDcu>
------------------------------------------------------------------------
[2021-05-13 12:55:25] sh-ya at ya dot ru
Description:
------------
using the variance requires pre-definition of classes that use traits
Test script:
---------------
interface Animal {
public function eat(AnimalFood $food);
}
class Dog implements Animal {
public function eat(Food $food) {}
}
trait SomeTrait {
public $b = true;
}
class Food {
use SomeTrait;
public $i = 0;
}
class AnimalFood extends Food {}
var_dump(new AnimalFood);
Expected result:
----------------
object(AnimalFood)#1 (2) {
["i"]=>
int(0)
["b"]=>
bool(true)
}
Actual result:
--------------
Fatal error: Could not check compatibility between Dog::eat(Food $food) and Animal::eat(AnimalFood
$food), because class AnimalFood is not available in ...
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=81038&edit=1