ejsmont-artur/php-proxy-builder
Runtime proxy builder for PHP that wraps any object with Advice (AOP-style) to add cross-cutting behavior like caching. Proxies transparently delegate method calls to the target while keeping proxy, advice, and client code fully decoupled.
Library allowing you to add proxy objects around arvitrary class instances to add behaviour at runtime.
Library employs concepts of Aspect Oriented Programming where a certain logic (like caching) is reused across the application without coupling the application code to the caching implementation.
<?php
// target instances to be proxied
$target = new SlowService();
// Advice implementing additional logic.
// We will integrate with frameworks to obtain $cacheBackendAdapter from your framework of choice like symfony2.
$advice = new CachingAdvice($cacheBackendAdapter);
$factory = new MagicMethodBasedFactory();
$proxiedService = $factory->createProxy($advice, $target);
// Call is made directly on the object, it's slow.
$target->getSomeData(12345);
// Calls are made through the proxy, which delegates to the CachingAdvice and then to target instance.
// First call is slow, the second call is fast as it is being cached.
$proxiedService->getSomeData(12345);
$proxiedService->getSomeData(12345);
The code you can see now has full test coverage but it is just the first implementation of the library.
Current implementation is based on magic methods. Because of this fact proxy does not inherit nor extend the proxied object so it does not pass type hint checks nor instanceof checks.
In near future we will provide a second implementation that will allow you to create a full interface based proxy from any object. This way proxy will be fully interchangable with the target instance and will pass type checks like:
<?php
($proxiedService instanceof SlowService) == true;
($proxiedService instanceof CachingAdvice) == false;
Please have a look at unit tests to see more examples of how the code should be used and assembled.
Library gains a lot of value by providing simple yet useful implementations of advices. We decided to keep all external dependencies out of the core of the library so we do not have logger nor cache implementations. We will integrate with frameworks to provide implementations of our minimalistic interfaces stored in Adapter folder.
Please see below two sequence diagrams with imaginary clinet calling a "doSomething()" method on the Target Object.
Please notice that Advice object is independent from both client and target. It can be reaplaced and tested without any changes to the client not target code.


Tests are run via PHPUnit and it is assumed that you have phpunit installed if you want to run tests. You can run tests using ant, "ci" target generates documentation and code coverage report.
You can run all tests using any of the following commands:
ant
ant phpunit
ant ci
You can run selected test case by running:
cd tests
phpunit Unit/PhpProxyBuilder/Aop/ClosureAdviceTest.php
How can I help you explore Laravel packages today?