方法声明应与 PHP 中的父方法兼容

发布于 2024-09-06 19:20:57 字数 187 浏览 4 评论 0原文

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

燕归巢 2024-09-13 19:20:57

childClass::customMethod()parentClass::customMethod() 相比,具有不同的参数或不同的访问级别(公共/私有/受保护)。

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

逆光下的微笑 2024-09-13 19:20:57

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

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) {;}}

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

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

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.

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:

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.

错爱 2024-09-13 19:20:57

如果你想保持 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();
        // ...

    }
}

if you wanna keep OOP form without turning any error off, you can also:

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();
        // ...

    }
}
万劫不复 2024-09-13 19:20:57

只是为了在接口上下文中扩展此错误,如果您键入提示函数参数,如下所示:

interface A

use Bar;

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

Class B

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

如果您忘记包含 <如果在您的实现类(B 类)上使用 code>use 语句,那么即使方法参数相同,您也会收到此错误。

Just to expand on this error in the context of an interface, if you are type hinting your function parameters like so:

interface A

use Bar;

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

Class B

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

If you have forgotten to include the use statement on your implementing class (Class B), then you will also get this error even though the method parameters are identical.

羁〃客ぐ 2024-09-13 19:20:57

我在尝试从 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”的新方法。事实上,它们都在做同样的事情,只是返回一个类,但具有不同的命名空间,正如我之前所描述的。

希望这可以帮助别人。

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.

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.

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.

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.

Hope this can help someone.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文