Как вызвать метод grandparent без получения ошибки E_STRICT?

Иногда мне нужно выполнить метод grandparent (то есть обходить родительский метод), я знаю, что это запах кода, но иногда я не могу изменить другие классы (фреймворки, библиотеки и т. Д.).

В PHP мы можем сделать что-то вроде:

call_user_func(array(get_parent_class(get_parent_class($childObject)), 'grandParentMethod')); 

Проблема в том, что если у вас есть ошибки E_STRICT, вы получите сообщение об ошибке:

Строгие стандарты: нестатический метод GrandParent :: grandParentMethod () не следует называть статически …

Я нашел только одно решение для этого (без удаления E_STRICT), и это просто добавление @ для подавления ошибки.

Но это действительно уродливо, знает ли кто-нибудь лучшее решение?

Благодаря ! PS: Я не могу создать новый объект, например:

 $grandparent = get_parent_class(get_parent_class($son)); $gp= new $grandparent; $gp->grandParentMethod 

потому что мне нужно вызвать мой метод бабушки и дедушки в контексте $ son.

Вы можете использовать ReflectionMethod-> invoke ()

Пример:

 <?php class Grandpa { protected $age = 'very old'; public function sayMyAge() { return 'sayMyAge() in Grandpa should be very old. ' . 'My age is: ' . $this->age; } } class Pa extends Grandpa { protected $age = 'less old'; public function sayMyAge() { return 'sayMyAge() in Pa should be less old. ' . 'My age is: ' . $this->age; } } class Son extends Pa { protected $age = 'younger'; public function sayMyAge() { return 'sayMyAge() in Son should be younger. ' . 'My age is: ' . $this->age; } } $son = new Son(); $reflectionMethod = new ReflectionMethod(get_parent_class(get_parent_class($son)), 'sayMyAge'); echo $reflectionMethod->invoke($son); // returns: // sayMyAge() in Grandpa should be very old. My age is: younger 

Примечание . Вызываемый метод должен быть общедоступным.

Вы можете вызвать дедушку или бабушку напрямую по имени (без привязки call_user_func ).

 class Base { protected function getFoo() { return 'Base'; } } class Child extends Base { protected function getFoo() { return parent::getFoo() . ' Child'; } } class Grandchild extends Child { protected function getFoo() { return Base::getFoo() . ' Grandchild'; } } 

Вызов Base::getFoo может выглядеть как статический вызов (из-за синтаксиса двоеточия), однако это не так. Точно так же, как parent:: не является статическим. Вызов метода из цепочки наследования в классе будет правильно привязывать значение $this , вызывать его как обычный метод, соблюдать правила видимости (например, защищенные) и не является нарушением какого-либо рода. Сначала это может показаться немного неудобным, но это способ сделать это на PHP.

Вы можете использовать отдельный внутренний метод (например, _doStuff для дополнения doStuff ) и вызвать его непосредственно у внука через родителя.

 // Base class that everything inherits class Grandpa { protected function _doStuff() { // grandpa's logic echo 'grandpa '; } public function doStuff() { $this->_doStuff(); } } class Papa extends Grandpa { public function doStuff() { parent::doStuff(); echo 'papa '; } } class Kiddo extends Papa { public function doStuff() { // Calls _doStuff instead of doStuff parent::_doStuff(); echo 'kiddo'; } } $person = new Grandpa(); $person->doStuff(); echo "\n"; $person = new Papa(); $person->doStuff(); echo "\n"; $person = new Kiddo(); $person->doStuff(); 

шоу

 grandpa grandpa papa grandpa kiddo