phpstan
phpstan copied to clipboard
Not throwing Method ... overrides method ... but misses parameter when compatible with an interface but not parent.
Bug report
An overridden method signature different than in a parent class is considered correct even though PHP throw Fatal error
.
I believe the issue comes from the fact that the method is compared to its prototype https://github.com/phpstan/phpstan-src/blob/1.8.x/src/Rules/Methods/MethodParameterComparisonHelper.php#L35 and the prototype is taken from here https://github.com/ondrejmirtes/BetterReflection/blob/5.8.x/src/Reflection/ReflectionMethod.php#L171, which is looking for an interface instead of the immediate parent method.
Code snippet that reproduces the problem
<?php declare(strict_types = 1);
interface A
{
public function test(): void;
}
class B implements A
{
public function test(mixed $a = null): void
{
}
}
class C extends B
{
public function test(): void
{
}
}
or links below:
https://phpstan.org/r/dafd527b-bf9f-484d-b660-237ef64309a7 - the error is marked for ExtendingClassNotImplementingSomeInterface
class only and ExtendingClassImplementingSomeInterface
is considered to be correct.
An example where PHP throws the following error https://3v4l.org/1PYEd#v8.1.9
Fatal error: Declaration of ExtendingClassImplementingSomeInterface::getList(mixed $a): void must be compatible with ImplementingSomeInterface::getList(mixed $a, bool $b = false): void in /in/1PYEd on line 19
Expected output
Method ExtendingClassImplementingSomeInterface::getList() overrides method ImplementingSomeInterface::getList() but misses parameter #2 $b.
Did PHPStan help you today? Did it make you happy in any way?
I run it before each commit :)
Maybe the same as https://github.com/phpstan/phpstan/issues/7388?
@canvural, it is very similar, thanks for the reference. I'm not sure if the bug you reported is caused by the same logic. In my case, I can see it is the method's prototype being taken from the (parent's) interface and the immediate parent method is ignored.
@jlekowski After the latest push in 1.11.x, PHPStan now reports different result with your code snippet:
@@ @@
+19: Method ExtendingClassImplementingSomeInterface::getList() overrides method ImplementingSomeInterface::getList() but misses parameter #2 $b.
35: Method ExtendingClassNotImplementingSomeInterface::getList() overrides method NotImplementingSomeInterface::getList() but misses parameter #2 $b.
Full report
Line | Error |
---|---|
19 | Method ExtendingClassImplementingSomeInterface::getList() overrides method ImplementingSomeInterface::getList() but misses parameter #2 $b. |
35 | Method ExtendingClassNotImplementingSomeInterface::getList() overrides method NotImplementingSomeInterface::getList() but misses parameter #2 $b. |
Thanks @ondrejmirtes :+1:
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.