添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams
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?

notJim has it exactly right. @waiwai933, if you could post the headers (just the first line: function customMethod( ... )) for each function we could tell you the specific problem – nickf Jun 25, 2010 at 3:41 More details about the error message and PHP compile time implications: bugs.php.net/bug.php?id=46851 – hakre May 21, 2013 at 9:15 My problem was that an argument was type-hinted but then I hadn't added use Closure; to the top of my class (since the type-hint was Closure). So... be sure to check whether you're missing dependencies like that. – Ryan Aug 27, 2017 at 0:51 Having the same exact argument default values is important as well. For example, parentClass::customMethod($thing = false) and childClass::customMethod($thing) would trigger the error, because the child's method hasn't defined a default value for the first argument. – Charles Jun 25, 2010 at 4:19 I believe visibility is actually a different error. By the way, at my shop we don't use strict mode, because of this (we use E_ALL, IIRC). – davidtbernal Jun 25, 2010 at 7:01 This has changed in PHP 5.4, btw: * E_ALL now includes E_STRICT level errors in the error_reporting configuration directive. See here: php.net/manual/en/migration54.other.php – Duncan Lock Nov 17, 2012 at 1:08

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.

in your last example - there shouldn't be an error here because it is legit, stdClass $a is more restrictive than mixed $a. is there a way to get around this? i mean in this case PHP should allow this but it still gives an error... – galchen Dec 22, 2012 at 17:38 Your last example is type-safe, so it certainly is "more restrictive than it needs to be". This may be a case of cargo-cult programming, since it conflicts with polymorphism in C++ and Java en.wikipedia.org/wiki/… – Warbo Apr 28, 2014 at 16:34 thanks for the explanation, in my case the first example you gave was exactly what was triggering my error. – But those new buttons though.. Jun 12, 2018 at 1:37 public function foo($a, $b, $c) {*/ public function foo() { list($a, $b, $c) = func_get_args(); // ... I would love to use this hack to get around these errors. I worry that there might be a performance penalty to this approach? I'll research this but if you have any resources to help answer that question, that'd be great. – Adam Friedman Feb 9, 2015 at 21:18 Depends on the situation I guess. Still Yes it maybe a bit hacky, but it's php? already, sometimes that can be a nice work around, thanks! <@ – Master James Jan 10, 2017 at 14:38 you saved my day! this was the only option to launch legacy php5 project on server with php7 without pain – vladkras Jun 4, 2019 at 14:37 For this case you can use default values instead of func_get_args(), i.e., in B, public function foo($a = null, $b = null, $c = null), as this does not break the contract promised by A. – Jake Oct 22, 2019 at 0:01

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.

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.

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.