Me preguntaba por qué no es posible crear complementos para protected
métodos. Hay esta pieza de código en 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;
}
Comprueba si el método es public
antes de permitir que sea interceptado. Se puede cambiar fácilmente mediante la creación de una preference
en el di.xml
de módulo propio, por supuesto, como este:
<?xml version="1.0"?>
<config>
<preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>
y reescribiendo _getClassMethods
con el \ReflectionMethod::IS_PUBLIC
cambio al \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED
interior del método.
Pero me pregunto por qué no es posible interceptar métodos protegidos en la definición de método original. ¿Tiene un impacto importante en el rendimiento, o hay alguna otra razón para eso, como permitir que los módulos de terceros hagan que la lógica de Magento sea demasiado "desordenada"?
Si no recuerdo mal de una presentación de Anton Krill, dijo que los métodos técnicamente protegidos pueden ser interceptados, pero frustra el propósito de tenerlos "protegidos".
La clase interceptor que se autogenera extiende la clase original para que tenga acceso a los métodos protegidos.
Pero ... Los métodos protegidos no deberían estar disponibles fuera de la clase.
Entonces es más una decisión que una limitación.
fuente
Es una característica de seguridad de OOPS no específica de magento.
Los métodos públicos, etiquetados por public, están disponibles para cada clase. Los métodos protegidos, etiquetados por protegido están disponibles para subclases y clases amigables, que son clases en el mismo paquete. Los métodos amigables, etiquetados por nada (es decir, por defecto) están disponibles para las clases amigables. Los métodos privados están disponibles solo para la clase misma.
Razones:
1) Los métodos protegidos no pueden acceder en el segundo nivel de herencia.
ejemplo: tomemos un ejemplo de dos clases Clase A y Clase B en el mismo paquete.
La clase B solo puede heredar los métodos protegidos y públicos de la clase A.
fuente
Protected methods... which are classes in the same package
- esto no es verdad. Los métodos protegidos solo están disponibles para las clases disponibles en la misma jerarquía mediante herencia, ya sea que estén en el mismo paquete o no, no hay diferencia.Protected Methods can't access in Inheritence second level.
- de nuevo, no es cierto - los métodos protegidos están disponibles en cualquier nivel de herencia, pero no desde fuera del alcance del objeto