严格标准:childClass::customMethod() 的声明应与parentClass::customMethod() 的声明兼容
PHP 中出现此错误的可能原因有哪些?我在哪里可以找到有关“兼容”含义的信息?
childClass::customMethod()
与
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 类的对象,它需要一个参数,因此调用将在运行时失败。
但是这永远不会失败并且不会触发错误
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) {;}}
这似乎比需要的限制更多,我认为这是由于内部原因。
可见性差异会导致不同的错误,但基本原因相同。没有任何方法比其父方法更不可见。
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();
// ...
}
}
use Bar;
interface A
{
public function foo(Bar $b);
}
class B implements A
{
public function foo(Bar $b);
}
如果您忘记在实现类(B 类)上包含
use
语句,那么即使方法参数相同,您也会收到此错误。
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”的新方法。事实上,它们都在做同样的事情,只是返回一个类,但具有不同的命名空间,正如我之前所描述的。
希望这可以帮助别人。
声明应与 (这里是父方法的签名)... 检查信息:报告覆盖的方法声明 与父类不兼容。仅启用检查 适用于 PHP 语言级别低于 8.0 的用户。
class A { public function foo($arg1, $arg2) { // ... } } class B extends A { /*instead of : public function foo($arg1, $arg2, $arg3, $arg4) { and so on...*/ public function foo($arg1, $arg2, $arg3 = '', $arg4 = false) { // or other default values with different types, and other number of arguments // ... } }