How to call grandparent method without getting E_STRICT error?

You can call the grandparent directly by name (does not need Reflection, nor 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';
    }
}

The Base::getFoo call may look like a static call (due to the colon :: syntax), however it is not. Just like parent:: isn't static, either.

Calling a method from the inheritance chain within a class will correctly bind the $this value, invoke it as a regular method, honour the visibility rules (e.g. protected), and is not a violation of any kind!

This may look a bit strange at first, but, this is the way to do it in PHP.


You may use ReflectionMethod->invoke()

Example:

<?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

Note: The invoked method must be public.