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: