[php] 메서드 선언은 PHP의 부모 메서드와 호환되어야합니다.

엄격한 표준 : childClass :: customMethod () 선언은 parentClass :: customMethod () 선언과 호환되어야합니다.

PHP에서이 오류의 가능한 원인은 무엇입니까? 호환성의 의미에 대한 정보는 어디에서 찾을 수 있습니까 ?



답변

childClass::customMethod()인수가 다르거 나 액세스 수준 (공개 / 개인 / 보호)이 parentClass::customMethod().


답변

이 메시지는 런타임에 실패 할 수있는 특정 가능한 메소드 호출이 있음을 의미합니다. 당신이 가지고 있다고 가정

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

그것은 필요한 것보다 더 제한적인 것처럼 보이며 내부 때문이라고 생각합니다.

가시성 차이로 인해 다른 오류가 발생하지만 기본적인 이유는 동일합니다. 부모 메서드보다 덜 눈에 띄는 메서드는 없습니다.


답변

오류를 끄지 않고 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();
        // ...

    }
}


답변

다음과 같이 함수 매개 변수에 힌트를 입력하는 경우 인터페이스 컨텍스트에서이 오류를 확장하면됩니다.

인터페이스 A

use Bar;

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

클래스 B

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

use구현 클래스 (Class B)에 문 을 포함하는 것을 잊은 경우 메서드 매개 변수가 동일하더라도이 오류가 발생합니다.


답변

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에서이 기능의 이점을 완전히 이해하지 못합니다. 입력 매개 변수의 재정의 및 / 또는 방법.

이전 aproach의 한 가지 단점은 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”라는 새 메소드를 작성했습니다. 사실 둘 다 똑같은 일을하면서 클래스를 반환하지만 앞서 설명한 것처럼 다른 네임 스페이스를 사용합니다.

이것이 누군가를 도울 수 있기를 바랍니다.


답변