Zastanawiałem się, dlaczego nie można tworzyć wtyczek dla protected
metod. Ten fragment kodu znajduje się w 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;
}
Sprawdza, czy metoda jest public
przed zezwoleniem na przechwycenie. To może być łatwo zmieniona przez stworzenie preference
w di.xml
własnego modułu, oczywiście, jak to:
<?xml version="1.0"?>
<config>
<preference for="Magento\Framework\Interception\Code\Generator\Interceptor" type="MyVendor\MyModule\Model\MyInterceptorModel" />
</config>
i przepisanie _getClassMethods
ze \ReflectionMethod::IS_PUBLIC
zmienionym na \ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED
wewnątrz metody.
Ale zastanawiam się, dlaczego nie jest możliwe przechwycenie chronionych metod w oryginalnej definicji metody? Czy ma to duży wpływ na wydajność, czy może ma to jakiś inny powód, na przykład pozwala innym modułom sprawić, że logika Magento będzie zbyt „nieuporządkowana”?
Jeśli dobrze pamiętam z prezentacji Antona Krilla, powiedział, że technicznie chronione metody mogą zostać przechwycone, ale to przeczy celowi ich „ochrony”.
Klasa przechwytująca, która jest generowana automatycznie, rozszerza klasę oryginalną, dzięki czemu ma dostęp do chronionych metod.
Ale ... Metody chronione nie powinny być dostępne poza klasą.
Więc jest to bardziej decyzja niż ograniczenie.
źródło
Jest to funkcja bezpieczeństwa OOPS, która nie jest specyficzna dla Magento.
Metody publiczne oznaczone przez public są dostępne dla każdej klasy. Metody chronione oznaczone jako chronione są dostępne dla podklas i klas przyjaznych, które są klasami w tym samym pakiecie. Przyjazne metody oznaczone jako nic (tj. Domyślne) są dostępne dla przyjaznych klas. Metody prywatne są dostępne tylko dla samej klasy.
Powody:
1) Metody chronione nie mogą uzyskać dostępu na drugim poziomie dziedziczenia.
przykład: Weźmy na przykład dwie klasy klasy A i klasy B w tym samym pakiecie.
Klasa B może chronić zarówno dziedziczone, jak i publiczne metody klasy A.
źródło
Protected methods... which are classes in the same package
- to nie jest prawda. Metody chronione są dostępne tylko dla klas dostępnych w tej samej hierarchii poprzez dziedziczenie - bez względu na to, czy są one w tym samym pakiecie, czy nie.Protected Methods can't access in Inheritence second level.
- znowu nieprawda - chronione metody są dostępne na dowolnym poziomie dziedziczenia, po prostu nie spoza zakresu obiektu