Skip to content

Ocramius ProxyManager or the great library that does the heavy lazy loading lifting for you

Within the next few lines, I will show you how you can use the proxy manager and how low the setup fee is compared to self written code.

The setup fee

Give is, that you have installed the ProxyManager with Composer. Than, create a script like the following (I will name it foo.php because I like it ;-)).

<?php
/**
 * @author stev leibelt <[email protected]>
 * @since 2017-12-12
 */

require_once __DIR__ . '/vendor/autoload.php';

use ProxyManager\Factory\LazyLoadingValueHolderFactory;
use ProxyManager\Configuration;

$configuration = new Configuration();
$configuration->setProxiesTargetDir(
    __DIR__ . '/../cache'
);

spl_autoload_register(
    $configuration->getProxyAutoloader()
);

class A
{
    /** @var mixed */
    private $foo;

    public function __construct(
        $foo
    ) {
        echo __METHOD__ . PHP_EOL;
        echo 'Something will take very long.' . PHP_EOL;
        sleep(5);
        $this->foo = $foo;
        echo 'Done.' . PHP_EOL;
    }

    public function __call($name, $arguments)
    {
        echo __METHOD__ . sprintf(
            'name: >>%s<<, list of arguments: >>%s<<.',
            $name,
            implode(
                ',',
                $arguments
            )
        ) . PHP_EOL;
    }

    public function foo()
    {
        echo $this->foo . PHP_EOL;
    }
}

class B extends A
{
    /** @var mixed */
    private $constructorFoo;

    /** @var bool */
    private $isNotInstantiated;

    public function __construct(
        $foo
    ) {
        echo __METHOD__ . PHP_EOL;
        echo 'Superfast.' . PHP_EOL;
        $this->constructorFoo       = $foo;
        $this->isNotInstantiated    = true;
        echo 'Done.' . PHP_EOL;
    }

    public function __call($name, $arguments)
    {
        $this->instantiateIfNeeded();

        parent::__call($name, $arguments); // TODO: Change the autogenerated stub
    }

    public function foo()
    {
        $this->instantiateIfNeeded();

        parent::foo(); // TODO: Change the autogenerated stub
    }

    private function instantiateIfNeeded()
    {
        if ($this->isNotInstantiated) {
            parent::__construct(
                $this->constructorFoo
            );

            $this->isNotInstantiated = false;
        }
    }
}

echo ':: Construct A' . PHP_EOL;
$a = new A('a');
echo ':: Construct B' . PHP_EOL;
$b = new B('b');
echo ':: Construct C' . PHP_EOL;
$factory = new LazyLoadingValueHolderFactory(
    $configuration
);
$c = $factory->createProxy(
    A::class,
    function (&amp; $wrappedObject, $proxy, $method, $parameters, &amp; $initializer) {
        $wrappedObject = new A('c'); // instantiation logic here
        $initializer   = null; // turning off further lazy initialization
    }
);

echo ':: Begin A' . PHP_EOL;
$a->foo();
$a->bar('foo', 'bar', 'baz');
echo ':: End A' . PHP_EOL;

echo ':: Begin B' . PHP_EOL;
$b->foo();
$b->bar('foo', 'bar', 'baz');
echo ':: End B' . PHP_EOL;

echo ':: Begin C' . PHP_EOL;
$c->foo();
$c->bar('foo', 'bar', 'baz');
echo ':: End C' . PHP_EOL;

And finally, execute it (clear && php foo.php).

What have we done - the explanation of the script

First, we are creating a class "A" that does some complicated stuff. Than, we are trying to implement our own lazy loading logic by creating a class "B". Afterwards we are instantiating A, B and A with the proxy manager. Finally, we are calling two methods for each instantiation.

When you execute the script, you quickly will figure out that the instantiation of $a is taking as long as expected while $b and $c are almost instantly there. At the end $b and $c will react the same.

Why should you use the proxy manager if you can archive the same stuff with "just some lines of code"? Because the proxy manager reduced your maintenance coast. If "A" would change, you would have need to extend or change "B" as well (e.g. A gets another method) while you don't have to touch any piece of code when using the proxy manager. Secondly, proxy manager is well tested and used. If you find an issue, you can fix it since the code is open source and do something good for the world - because sharing is caring.

Translate to de es fr it pt ja

Trackbacks

No Trackbacks

Comments

Display comments as Linear | Threaded

No comments

The author does not allow comments to this entry

Add Comment

Standard emoticons like :-) and ;-) are converted to images.
E-Mail addresses will not be displayed and will only be used for E-Mail notifications.
To leave a comment you must approve it via e-mail, which will be sent to your address after submission.

To prevent automated Bots from commentspamming, please enter the string you see in the image below in the appropriate input box. Your comment will only be submitted if the strings match. Please ensure that your browser supports and accepts cookies, or your comment cannot be verified correctly.
CAPTCHA

Markdown format allowed
Form options