为什么不能拦截受保护的方法?


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在允许方法被拦截之前检查方法是否存在。当然,可以通过preferencedi.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逻辑过于“混乱”?

Answers:


24

根据Magento文档,在受保护的方法上使用插件是“不可能的”。

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

您不能将插件应用于:

  • 最终方法
  • 期末课程
  • 任何包含至少一个最终公共方法的类
  • 非公开方法
  • 类方法(例如静态方法)
  • __构造虚拟类型

但是您的观点是正确的,根据中的___callPlugins定义Magento\Framework\Interception\Interceptor,使用受保护的方法不会出现任何问题。

我的第一个猜测是,他们限制了它以避免高代码复杂度,因为Magento应该重写任何受保护的方法并调用___callPlugins它们中的每一个...这将极大地降低恕我直言。

但是我认为真正的原因是出于逻辑上的一致性:应该使用插件来更改类方法的输出/输入,而不是重写内部行为,因此它们应该仅访问公共方法。

要重写内部行为,您必须使用首选项。这说得通。


1
好答案。我本人也想知道这一点,但是从OOP / SOLID的角度来看,仅允许截获公共方法是有意义的。
Giel Berkers

13

如果我从安东·克里尔(Anton Krill)的演讲中正确地记得,他说可以拦截技术上受保护的方法,但这违背了将它们“保护”的目的。
自动生成的拦截器类扩展了原始类,因此它可以访问受保护的方法。
但是...受保护的方法不应在类之外提供。
因此,这更多是决定而不是限制。


-4

它是OOPS安全功能,而不是magento特定的。

每个类都可以使用以public标记的公共方法。标记为protected的受保护方法可用于子类和友好类,它们是同一包中的类。友好的类可以使用没有标记(即默认)的友好方法。私有方法仅对类本身可用。

原因:

1)受保护的方法无法在继承二级中访问。

示例:让我们以同一包中的两个A类和B类为例。

B类只能继承受保护的类,也不能使用A类的公共方法。


4
Protected methods... which are classes in the same package- 这不是真的。受保护的方法仅可用于通过继承在相同层次结构中可用的类-不管它们是否在同一包中,都没有区别。Protected Methods can't access in Inheritence second level.-再次,不是正确的-受保护的方法可以在任何继承级别使用,只是不能从对象范围之外使用
Robbie Averill
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.