保護されたメソッドを傍受できないのはなぜですか?


14

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インターセプトされる前にするします。もちろん、次のようにpreferencein di.xmlofのモジュールを作成することで簡単に変更できます。

<?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のロジックを「乱雑」にできるようにするなど、他の理由がありますか?

回答:


24

Magentoのドキュメントによると、保護されたメソッドでプラグインを使用することは「不可能」です。

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

プラグインを以下に適用することはできません。

  • 最終的な方法
  • 最終クラス
  • 少なくとも1つの最終パブリックメソッドを含むクラス
  • 非公開メソッド
  • クラスメソッド(静的メソッドなど)
  • __construct仮想型

しかし、あなたのポイントは正しいです、の___callPlugins定義によるとMagento\Framework\Interception\Interceptor、保護されたメソッドを使用しても問題は見られません。

私の最初の推測は、Magentoが保護されたメソッドを書き換えて呼び出す必要があるため、コードの複雑さを避けるためにそれを制限したことです ___callPluginsて、それらのそれぞれをです...それは私見をひどく遅くします。

しかし、本当の理由は論理的な一貫性のためだと思います:プラグインはクラスのメソッドoutput / inputを変更するために使用されるべきであり、内部の振る舞いを書き換えるためではありません。

内部動作を書き換えるには、設定を使用する必要があります。それは理にかなっている。


1
いい答えです。私自身もこれを疑問に思っていましたが、OOP / SOLIDの観点からは、パブリックメソッドの傍受のみを許可するのが理にかなっています。
ゲルバーカーズ

13

アントン・クリルのプレゼンテーションから私が正しく覚えているなら、彼は技術的に保護された方法は傍受される可能性があるが、それらを「保護する」という目的に反すると述べた。
自動生成されるインターセプタークラスは、保護されたメソッドにアクセスできるように元のクラスを拡張します。
しかし...保護されたメソッドは、クラスの外部では使用できません。
ですから、それは制限というよりも決定です。


-4

これはmagento固有ではないOOPSセキュリティ機能です。

publicというラベルの付いたパブリックメソッドは、すべてのクラスで使用できます。protectedというラベルの付いた保護されたメソッドは、同じパッケージ内のクラスであるサブクラスとフレンドリクラスで使用できます。何も表示されていないフレンドリーなメソッド(デフォルト)は、フレンドリーなクラスで使用できます。プライベートメソッドは、クラス自体でのみ使用できます。

理由:

1)保護されたメソッドは、継承の第2レベルではアクセスできません。

例:同じパッケージ内のクラスAとクラスBの2つのクラスの例を見てみましょう。

クラスBは、クラスAのパブリックメソッドだけでなく、継承保護のみを行うことができます。


4
Protected methods... which are classes in the same package- 本当じゃない。保護されたメソッドは継承を介して同じ階層で使用可能なクラスでのみ使用可能です-同じパッケージ内にあるかどうかにかかわらず、違いはありません。Protected Methods can't access in Inheritence second level.-再度、真実ではない-保護された方法は、単にない対象範囲外から、遺伝の任意のレベルで利用可能である
ロビーアベリル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.