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?


Solution 1:

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

Solution 2:

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.

Solution 3:

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

    }
}

Solution 4:

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.