왜 보호 된 방법을 가로 챌 수 없습니까? $methods[]

protected메소드 용 플러그인을 만들 수 없는지 궁금했습니다 . 이 코드는 다음과 Magento\Framework\Interception\Code\Generator\Interceptor같습니다.

protected function _getClassMethods()
{
    $methods = [$this->_getDefaultConstructorDefinition()];

    $reflectionClass = new \ReflectionClass($this->getSourceClassName());
    $publicMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);
    foreach ($publicMethods as $method) {
        if ($this->isInterceptedMethod($method)) {
            $methods[] = $this->_getMethodInfo($method);
        }
    }
    return $methods;
}

메소드가 public인터셉트되기 전에 있는지 확인합니다 . 그것은 쉽게를 작성하여 변경 될 수 preference에서 di.xml다음과 같이 물론, 자신의 모듈 :

<?xml version="1.0"?>
<config>
    <preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>

및 재기록 _getClassMethods(가)로 \ReflectionMethod::IS_PUBLIC변경 \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED하는 방법의 내부.

그러나 원래 메서드 정의에서 보호 된 메서드를 가로 챌 수없는 이유가 무엇입니까? 성능에 큰 영향을 미치거나 타사 모듈이 Magento 논리를 “지저분하게”만들도록 허용하는 것과 같은 다른 이유가 있습니까?



답변

Magento 문서에 따르면 보호 된 메소드에서 플러그인을 사용하는 것은 “가능한”것이 아닙니다.

( http://devdocs.magento.com/guides/v2.0/extension-dev-guide/plugins.html )

다음에 플러그인을 적용 할 수 없습니다.

  • 최종 방법
  • 최종 수업
  • 하나 이상의 최종 공개 메소드를 포함하는 모든 클래스
  • 비공개 방법
  • 클래스 메서드 (정적 메서드 등)
  • __ 구문 가상 유형

하지만 당신의 포인트에 따라, 올바른 ___callPlugins에서 정의Magento\Framework\Interception\Interceptor 보호 된 방법을 사용하는 데 아무런 문제가 없습니다.

내 첫 번째 추측은 Magento가 보호 된 메소드를 다시 작성하고 ___callPlugins각 메소드를 호출해야하기 때문에 높은 코드 복잡성을 피하기 위해 제한했습니다 .IMHO 가 크게 느려질 것입니다.

그러나 진정한 이유는 논리적 일관성에 있다고 생각합니다. 플러그인은 내부 동작을 다시 쓰지 않고 클래스 메소드 output / input을 변경하는 데 사용해야하므로 공용 메소드에만 액세스해야합니다.

내부 동작을 다시 쓰려면 환경 설정을 사용해야합니다. 말된다.


답변

Anton Krill의 프레젠테이션에서 올바르게 기억한다면 기술적으로 보호 된 방법은 가로 챌 수 있지만 “보호 된”방법의 목적을 상실한 것입니다.
자동 생성 된 인터셉터 클래스는 원래 클래스를 확장하여 보호 된 메소드에 액세스 할 수 있습니다.
그러나 … 보호 된 메소드는 클래스 외부에서 사용할 수 없습니다.
따라서 그것은 제한보다 더 많은 결정입니다.


답변

마 젠토와 관련이없는 OOPS 보안 기능입니다.

모든 클래스에서 public으로 레이블이 지정된 공용 메소드를 사용할 수 있습니다. protected로 표시된 보호 된 메소드는 서브 패키지 및 친숙한 클래스에서 사용 가능하며, 동일한 클래스의 클래스입니다. 친숙한 클래스에는 아무것도 표시되지 않은 친숙한 메서드 (예 : 기본값)를 사용할 수 있습니다. 개인 메서드는 클래스 자체에서만 사용할 수 있습니다.

원인:

1) 보호 된 메소드는 상속 2 단계에서 액세스 할 수 없습니다.

예제 : 클래스 A와 클래스 B의 두 클래스를 동일한 패키지로 예를 들어 보겠습니다.

클래스 B는 상속 A 클래스의 공용 메소드뿐만 아니라 상속 만 보호 할 수 있습니다.


답변