Declaration of Methods should be Compatible with Parent Methods in PHP

Strict Standards: Declaration of childClass::customMethod() should be compatible with that of parentClass::customMethod()

What are possible causes of this error in PHP? Where can I find information about what it means to be compatible?

150448 次浏览

childClass::customMethod() has different arguments, or a different access level (public/private/protected) than parentClass::customMethod().

此消息意味着某些可能的方法调用可能在运行时失败

class A { public function foo($a = 1) {;}}
class B extends A { public function foo($a) {;}}
function bar(A $a) {$a->foo();}

编译器只根据不需要参数的 A: : foo ()的要求检查 $a-> foo ()调用。$a 可能是 B 类的一个对象,它需要一个参数,因此调用在运行时会失败。

This however can never fail and does not trigger the error

class A { public function foo($a) {;}}
class B extends A { public function foo($a = 1) {;}}
function bar(A $a) {$a->foo();}

因此,没有哪个方法可能比它的父方法具有更多的所需参数。

当类型提示不匹配时,也会生成相同的消息,但在这种情况下,PHP 的限制更多。这就产生了一个错误:

class A { public function foo(StdClass $a) {;}}
class B extends A { public function foo($a) {;}}

还有这个:

class A { public function foo($a) {;}}
class B extends A { public function foo(StdClass $a) {;}}

这似乎比它需要的限制更多,我认为这是由于内部。

可见性差异会导致不同的错误,但基本原因相同。任何方法都不能比其父方法更不可见。

如果希望保持 OOP 形式而不关闭任何错误,还可以:

class A
{
public function foo() {
;
}
}
class B extends A
{
/*instead of :
public function foo($a, $b, $c) {*/
public function foo() {
list($a, $b, $c) = func_get_args();
// ...


}
}

在接口上下文中展开这个错误,如果类型提示函数参数,如下所示:

接口 A

use Bar;


interface A
{
public function foo(Bar $b);
}

类别 B

class B implements A
{
public function foo(Bar $b);
}

如果忘记在实现类(类 B)中包含 use语句,那么即使方法参数相同,也会得到这个错误。

我在尝试从 GitHub 扩展现有类时遇到了这个问题。我会试着解释我自己,首先写出我认为应该写的类,然后是现在的类。

我怎么想的

namespace mycompany\CutreApi;


use mycompany\CutreApi\ClassOfVendor;


class CutreApi extends \vendor\AwesomeApi\AwesomeApi
{
public function whatever(): ClassOfVendor
{
return new ClassOfVendor();
}
}

我终于做到了

namespace mycompany\CutreApi;


use \vendor\AwesomeApi\ClassOfVendor;


class CutreApi extends \vendor\AwesomeApi\AwesomeApi
{
public function whatever(): ClassOfVendor
{
return new \mycompany\CutreApi\ClassOfVendor();
}
}

因此,当您使用一个返回名称空间类的方法并尝试使用其他名称空间返回相同的类时,似乎也会出现这个错误。幸运的是,我已经找到了这个解决方案,但是我还没有完全理解 php 7.2中这个特性的好处,对我来说,根据需要重写现有的类方法是很正常的,包括重新定义输入参数和/或甚至方法的行为。

前一种方法的一个缺点是 IDE 无法识别在 mycompany CutreApi ClassOfVendor ()中实现的新方法。因此,现在,我将使用这个实现。

马上就好

namespace mycompany\CutreApi;


use mycompany\CutreApi\ClassOfVendor;


class CutreApi extends \vendor\AwesomeApi\AwesomeApi
{
public function getWhatever(): ClassOfVendor
{
return new ClassOfVendor();
}
}

因此,我没有尝试使用“ whatever”方法,而是编写了一个名为“ getWhatever”的新方法。实际上,它们都在做同样的事情,只是返回一个类,但是使用的名称空间不同,就像我之前描述的那样。

希望这个能帮到别人。