Calling private/protected PHP methods


Generally, private or protected methods should not be accessible outside the class. But if you’re writing a unit test, you can break this rule.

Given PHP class with private method:

class Foo
{
    private function bar(): string
    {
        return 'baz';
    }
}

Reflection

Use Reflection to call the method outside the class:

$reflectionClass = new ReflectionClass(Foo::class);
$reflectionMethod = $reflectionClass->getMethod('bar');
$reflectionMethod->setAccessible(true);
$reflectionMethod->invoke(new Foo()); // 'baz'

Reflection works for both private and protected methods.

Alternatively, this can be refactored and simplified to ReflectionMethod:

$reflectionMethod = new ReflectionMethod(Foo::class, 'bar');
$reflectionMethod->setAccessible(true);
$reflectionMethod->invoke(new Foo()); // 'baz'

To pass method arguments, use ReflectionMethod::invokeArgs:

$args = [1, 2, 3];
$reflectionMethod->invokeArgs(new Foo(), $args);

Here’s a reusable function that calls a class instance method:

/**
 * Calls object method with arguments.
 *
 * @param object $object
 * @param string $method
 * @param array $args
 * @return mixed
 */
function callObjectMethod(object $object, string $method, array $args = [])
{
    $reflectionMethod = new ReflectionMethod(get_class($object), $method);
    $reflectionMethod->setAccessible(true);
    return $reflectionMethod->invokeArgs($object, $args);
}

This means you can call Foo::bar:

callObjectMethod(new Foo(), 'bar'); // 'baz'

Demo

See Repl.it:



If you enjoyed this post, please consider supporting this site!