Мне было интересно, почему невозможно создать плагины для 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 слишком «грязной»?
Если я правильно помню из выступления Антона Криля, он сказал, что технически защищенные методы могут быть перехвачены, но это противоречит цели их "защиты".
Класс перехватчика, который создается автоматически, расширяет исходный класс, поэтому у него есть доступ к защищенным методам.
Но ... Защищенные методы не должны быть доступны вне класса.
Так что это скорее решение, чем ограничение.
источник
Это функция безопасности OOPS, не зависящая от magento.
Публичные методы, помеченные как public, доступны для каждого класса. Защищенные методы, помеченные защищенными, доступны для подклассов и дружественных классов, которые являются классами в одном пакете. Дружественные методы, помеченные ничем (то есть по умолчанию), доступны для дружественных классов. Приватные методы доступны только самому классу.
Причины:
1) Защищенные методы не могут получить доступ на втором уровне наследования.
пример: давайте возьмем для примера два класса Class A и Class B в одном пакете.
Класс B может защищать только наследование, а также общедоступные методы класса A.
источник
Protected methods... which are classes in the same package
- это неправда. Защищенные методы доступны только для классов, доступных в одной иерархии через наследование - независимо от того, находятся они в одном пакете или нет, не имеет значения.Protected Methods can't access in Inheritence second level.
- опять же, это не так - защищенные методы доступны на любом уровне наследования, но только за пределами области видимости объекта