方法的声明应该与 PHP 中的父方法兼容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3115388/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Declaration of Methods should be Compatible with Parent Methods in PHP
提问by waiwai933
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?
PHP 中出现此错误的可能原因是什么?我在哪里可以找到关于兼容意味着什么的信息?
回答by davidtbernal
childClass::customMethod()has different arguments, or a different access level (public/private/protected) than parentClass::customMethod().
childClass::customMethod()与parentClass::customMethod().
回答by ldrut
This message means that there are certain possible method calls which may fail at run-time. Suppose you have
此消息意味着某些可能的方法调用可能会在运行时失败。假设你有
class A { public function foo($a = 1) {;}}
class B extends A { public function foo($a) {;}}
function bar(A $a) {$a->foo();}
The compiler only checks the call $a->foo() against the requirements of A::foo() which requires no parameters. $a may however be an object of class B which requires a parameter and so the call would fail at runtime.
编译器只根据不需要参数的 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();}
So no method may have more required parameters than its parent method.
因此,没有任何方法可能比其父方法具有更多的必需参数。
The same message is also generated when type hints do not match, but in this case PHP is even more restrictive. This gives an error:
当类型提示不匹配时也会生成相同的消息,但在这种情况下 PHP 的限制更加严格。这给出了一个错误:
class A { public function foo(StdClass $a) {;}}
class B extends A { public function foo($a) {;}}
as does this:
就像这样:
class A { public function foo($a) {;}}
class B extends A { public function foo(StdClass $a) {;}}
That seems more restrictive than it needs to be and I assume is due to internals.
这似乎比它需要的更具限制性,我认为是由于内部原因。
Visibility differences cause a different error, but for the same basic reason. No method can be less visible than its parent method.
可见性差异导致不同的错误,但出于相同的基本原因。没有任何方法可以比其父方法更不可见。
回答by Sajjad Shirazy
if you wanna keep OOP form without turning any error off, you can also:
如果您想在不关闭任何错误的情况下保持 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();
// ...
}
}
回答by Spholt
Just to expand on this error in the context of an interface, if you are type hinting your function parameters like so:
只是为了在接口的上下文中扩展此错误,如果您键入提示您的函数参数,如下所示:
interface A
接口A
use Bar;
interface A
{
public function foo(Bar $b);
}
Class B
B级
class B implements A
{
public function foo(Bar $b);
}
If you have forgotten to include the usestatement on your implementing class (Class B), then you will also get this error even though the method parameters are identical.
如果您忘记use在实现类(B 类)中包含该语句,那么即使方法参数相同,您也会收到此错误。
回答by Ferran
I faced this problem while trying to extend an existing class from GitHub. I'm gonna try to explain myself, first writing the class as I though it should be, and then the class as it is now.
我在尝试从 GitHub 扩展现有类时遇到了这个问题。我将尝试解释自己,首先按照我应该的方式编写课程,然后按照现在的方式编写课程。
What I though
我虽然
namespace mycompany\CutreApi;
use mycompany\CutreApi\ClassOfVendor;
class CutreApi extends \vendor\AwesomeApi\AwesomeApi
{
public function whatever(): ClassOfVendor
{
return new ClassOfVendor();
}
}
What I've finally done
我最终做了什么
namespace mycompany\CutreApi;
use \vendor\AwesomeApi\ClassOfVendor;
class CutreApi extends \vendor\AwesomeApi\AwesomeApi
{
public function whatever(): ClassOfVendor
{
return new \mycompany\CutreApi\ClassOfVendor();
}
}
So seems that this errror raises also when you're using a method that return a namespaced class, and you try to return the same class but with other namespace. Fortunately I have found this solution, but I do not fully understand the benefit of this feature in php 7.2, for me it is normal to rewrite existing class methods as you need them, including the redefinition of input parameters and / or even behavior of the method.
因此,当您使用返回命名空间类的方法时,似乎也会引发此错误,并且您尝试使用其他命名空间返回相同的类。幸运的是我找到了这个解决方案,但我不完全理解这个特性在 php 7.2 中的好处,对我来说,根据需要重写现有的类方法是正常的,包括重新定义输入参数和/或什至行为方法。
One downside of the previous aproach, is that IDE's could not recognise the new methods implemented in \mycompany\CutreApi\ClassOfVendor(). So, for now, I will go with this implementation.
前一种方法的一个缺点是 IDE 无法识别在 \mycompany\CutreApi\ClassOfVendor() 中实现的新方法。所以,现在,我将采用这个实现。
Currently done
目前完成
namespace mycompany\CutreApi;
use mycompany\CutreApi\ClassOfVendor;
class CutreApi extends \vendor\AwesomeApi\AwesomeApi
{
public function getWhatever(): ClassOfVendor
{
return new ClassOfVendor();
}
}
So, instead of trying to use "whatever" method, I wrote a new one called "getWhatever". In fact both of them are doing the same, just returning a class, but with diferents namespaces as I've described before.
因此,我没有尝试使用“whatever”方法,而是编写了一个名为“getWhatever”的新方法。事实上,他们都在做同样的事情,只是返回一个类,但正如我之前描述的那样,具有不同的命名空间。
Hope this can help someone.
希望这可以帮助某人。

