Doc #81038 [Com]: Early binding limitations insufficiently documented

[email protected] ("austinpatrick711 at gmail dot com") Wed, 30 Nov 2022 05:16:06 +0000
Newsgroups php.doc.bugs
Message-ID <[email protected]>
Edit report at https://bugs.php.net/bug.php?id=81038&edit=1

 ID:                 81038
 Comment by:         austinpatrick711 at gmail dot com
 Reported by:        sh-ya at ya dot ru
 Summary:            Early binding limitations insufficiently documented
 Status:             Open
 Type:               Documentation Problem
 Package:            Scripting Engine problem
 PHP Version:        7.4.19
 Block user comment: N
 Private report:     N

 New Comment:

A really good post, very thankful and hopeful that you will write many more posts like this one.		

(https://www.tellpopeyes.ltd/)php.net


Previous Comments:
------------------------------------------------------------------------
[2021-05-17 13:54:48] [email protected]

Traits (and for that matter interfaces) prevent early binding. Early binding if a legacy feature that we have no plans to extend. You should either declare classes in the correct order or use autoloading.

As such, I am moving this back to docs.

------------------------------------------------------------------------
[2021-05-17 13:13:13] [email protected]

Maybe there is actually a bug, but I don't think it will be fixed.

------------------------------------------------------------------------
[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] [email protected]

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