It is possible in Better Reflection to replace the body statements of a function in the reflection - in essence, giving the ability to monkey patch the code.
Given the following class under reflection:
class MyClass
{
public function foo()
{
return 5;
}
}
You can replace the body of the function like so:
<?php
use Roave\BetterReflection\BetterReflection;
$classInfo = (new BetterReflection())->classReflector()->reflect('MyClass');
$classInfo->getMethod('foo')->setBody(function () {
return 4;
});
This does not take immediate effect on execution - and in fact, if the class is already loaded, it is impossible to overwrite the in-memory class (this is a restriction in PHP itself). However, if you have reflected on this class in such a way that it is not already in memory, it is possible to load this class using Better Reflection's own autoload system (make sure this is added after any other autoloader, otherwise it may not behave correctly.
<?php
// Call this anywhere after all other autoloaders are registered (e.g. Composer)
use Roave\BetterReflection\Util\Autoload\ClassLoader;
use Roave\BetterReflection\Util\Autoload\ClassLoaderMethod\FileCacheLoader;
$loader = new ClassLoader(FileCacheLoader::defaultFileCacheLoader(__DIR__));
// Call this any time before instantiating the class
$loader->addClass($classInfo);
$c = new MyClass();
var_dump($c->foo()); // This will now be 4, not 5...
But, you probably shouldn't do this ;)
Loader methods available are:
FileCacheLoader
- cache the file contents (no cache invalidation). Example usage is above; it's recommended to use thedefaultFileCacheLoader
static constructor to simplify creation. Pass the directory to store cached files as the parameter.EvalCacheLoader
- as the naming suggests, useseval
to bring the class into scope. This is not ideal if you're after performance.