Декларация методов должна быть совместима с родительскими методами в PHP

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

Каковы возможные причины этой ошибки в PHP? Где я могу найти информацию о том, что значит быть совместимым?

Ответ 1

childClass::customMethod() имеет разные аргументы или другой уровень доступа (открытый/закрытый/защищенный), чем parentClass::customMethod().

Ответ 2

Это сообщение означает, что есть определенные возможные вызовы методов, которые могут не работать во время выполнения. Предположим, что у вас есть

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

Это кажется более ограничительным, чем должно быть, и я предполагаю, что это связано с внутренними функциями.

Различия видимости вызывают другую ошибку, но по той же основной причине. Никакой метод не может быть менее заметным, чем его родительский метод.

Ответ 3

Если вы хотите сохранить форму ООП без выключения какой-либо ошибки, вы также можете:

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

    }
}

Ответ 4

Просто для того, чтобы расширить эту ошибку в контексте интерфейса, если вы вводите типы параметров, например:

интерфейс A

use Bar;

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

Класс B

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

Если вы забыли включить оператор use в свой класс реализации (класс B), вы также получите эту ошибку, даже если параметры метода идентичны.

Ответ 5

Абстрактный класс A

abstract class A {
    function foo();
}

Класс ребенка B

class B {
    function foo($a=null, $b=null, $c=null)
    {
        //do what you want with the parameters.
    }
}

Instance:

$b = new B();
$b->foo();
$b->($m, $n, $l);

Цель состоит в том, чтобы сделать как $b->foo, так и $b->($m, $n, $l) работоспособными.