So I have 4 classes
class BaseConstraints {}
class ChildConstraints extends BaseConstraints {}
class BaseClass {
function someMethod(BaseConstraints $baseConstraints) {}
}
class ChildClass extends BaseClass {
function someMethod(ChildConstraints $childConstraints) {
parent::someMethod($childConstraints)
}
}
When running under PHP 7 everything was great. Having upgraded to PHP 8.1, I'm getting the error Declaration of ChildClass::someMethod(ChildConstraints $childConstraints) must be compatible with BaseClass::someMethod(BaseConstraints $bConstraints)
Given that the child classes extend the base classes, I'm not entirely too sure why that would be having that issue. In PHP 7, if I run the following
$a = new ChildClass();
echo var_export(is_a($a, 'BaseClass'), true);
$b = new ChildConstraints();
echo var_export(is_a($b, 'BaseConstraints'), true);
both print out true
. So why does PHP 8 complain about the incompatibility if ChildConstraints
is a BaseConstraints
? Beyond that, though, how can I address this situation? We have cases like the above all throughout our codebase -- hundreds, if not thousands, of them -- so I'm worried about potential solutions. Off the top of my head, I can think of 3 routes to take:
have all the child classes, when type-hinting a child method overriding the parent, revert to using the base class everywhere. I don't really like that because there could be complaints accessing methods evident only in the child class.
use interfaces. I tried that just to see for BaseConstraints and PHP didn't throw a fatal. But using this solution, I would have to create an interface that both the base class and all of its child classes implement. Then change all the signatures to use the interface.
stop type-hinting where derived classes are utilized
None of those seem ideal. Is there something else I can do?
thnx,
Christoph