ProxyManager

## Proxy Manager

This library aims at providing abstraction for generating various kinds of proxy classes.

If you want to learn more about proxy pattern watch this video:

### Installation

The suggested installation method is via composer.

    php composer.phar require ocramius/proxy-manager:1.0.*

### Lazy Loading Value Holders (Virtual Proxy)

ProxyManager can generate lazy loading value holders, which are virtual proxies capable of saving performance and memory for objects that require a lot of dependencies or CPU cycles to be loaded: particularly useful when you may not always need the object, but are constructing it anyways.

    $factory = new \ProxyManager\Factory\LazyLoadingValueHolderFactory();

    $proxy = $factory->createProxy(
        'MyApp\HeavyComplexObject',
        function (& $wrappedObject, $proxy, $method, $parameters, & $initializer) {
            $wrappedObject = new HeavyComplexObject(); // instantiation logic here
            $initializer   = null; // turning off further lazy initialization

            return true;
        }
    );

    $proxy->doFoo();

See the complete documentation about lazy loading value holders.

### Access Interceptor Value Holder

An access interceptor value holder is a smart reference that allows you to execute logic before and after a particular method is executed or a particular property is accessed, and it allows to manipulate parameters and return values depending on your needs.

    $factory = new \ProxyManager\Factory\AccessInterceptorValueHolderFactory();

    $proxy = $factory->createProxy(
        new \My\Db\Connection(),
        array('query' => function () { echo "Query being executed!\n"; }),
        array('query' => function () { echo "Query completed!\n"; })
    );

    $proxy->query(); // produces "Query being executed!\nQuery completed!\n"

See the complete documentation about access interceptor value holders.

### Access Interceptor Scope Localizer

An access interceptor scope localizer works exactly like an access interceptor value holder, but it is safe to use to proxy fluent interfaces.

See the complete documentation about access interceptor scope localizer.

### Null Objects

A Null Object proxy implements the null object pattern.

This kind of proxy allows you to have fallback logic in case loading of the wrapped value failed.

    $factory = new \ProxyManager\Factory\NullObjectFactory();

    $proxy = $factory->createProxy('My\EntityObject');

    $proxy->getName(); // empty return

A Null Object Proxy can be created from an object, a class name or an interface name:

    $factory = new \ProxyManager\Factory\NullObjectFactory();

    $proxy = $factory->createProxy('My\EntityObjectInterface');
    $proxy->getName(); // empty return

    $proxy = $factory->createProxy($entity); // created from object
    $proxy->getName(); // empty return

See the complete documentation about null object proxy.

### Ghost Objects

Similar to value holder, a ghost object is usually created to handle lazy loading.

The difference between a value holder and a ghost object is that the ghost object does not contain a real instance of the required object, but handles lazy loading by initializing its own inherited properties.

ProxyManager can generate lazy loading ghost objects, which are proxies used to save performance and memory for large datasets and graphs representing relational data. Ghost objects are particularly useful when building data-mappers.

Additionally, the overhead introduced by ghost objects is very low when compared to the memory and performance overhead caused by virtual proxies.

    $factory = new \ProxyManager\Factory\LazyLoadingGhostFactory();

    $proxy = $factory->createProxy(
        'MyApp\HeavyComplexObject',
        function ($proxy, $method, $parameters, & $initializer) {
            $initializer   = null; // turning off further lazy initialization

            // modify the proxy instance
            $proxy->setFoo('foo');
            $proxy->setBar('bar');

            return true;
        }
    );

    $proxy->doFoo();

See the complete documentation about lazy loading ghost objects.

### Remote Object

A remote object proxy is an object that is located on a different system, but is used as if it was available locally. There's various possible remote proxy implementations, which could be based on xmlrpc/jsonrpc/soap/dnode/etc.

This example uses the XML-RPC client of Zend Framework 2:

    interface FooServiceInterface
    {
        public function foo();
    }

    $factory = new \ProxyManager\Factory\RemoteObjectFactory(
        new \ProxyManager\Factory\RemoteObject\Adapter\XmlRpc(
            new \Zend\XmlRpc\Client('https://example.com/rpc-endpoint')
        )
    );

    // proxy is your remote implementation
    $proxy = $factory->createProxy('FooServiceInterface');

    var_dump($proxy->foo());

See the complete documentation about remote objects.

### Contributing

Please read the CONTRIBUTING contents if you wish to help out!

### Credits

The idea was originated by a talk about Proxies in PHP OOP that I gave at the @phpugffm in January 2013.