Using Virtual Agent to Realize Delayed Loading Technology in PHP

  • 2021-07-26 06:56:36
  • OfStack

It is said that this product is learned from Martin's "Enterprise Application Architecture Pattern", which assists PHP's dynamic language features and can realize delayed loading much easier than Java-through a virtual proxy placeholder. The only defect of 1 is that it can only proxy objects, not built-in basic types.

In the design of PHP domain model, I also used this to realize the delayed loading of DomainObject.


 * Virtual proxy, which calls the closure function to generate the target object only when the member is accessed.
 *
 * @author tonyseek
 *
 */
class VirtualProxy
{
    private $holder = null;
    private $loader = null;     /**
     * Virtual proxy, which calls the closure function to generate the target object only when the member is accessed.
     *
     * @param Closure $loader Generate the closure function of the proxy object
     */
    public function __construct(Closure $loader)
    {
            $this->loader = $loader;
    }     /**
     * Call of proxy member method
     *
     * @param string $method
     * @param array  $arguments
     * @throws BadMethodCallException
     * @return mixed
     */
    public function __call($method, array $arguments = null)
    {
            $this->check();             if (!method_exists($this->holder, $method)) {
                    throw new BadMethodCallException();
            }             return call_user_func_array(
                    array(&$this->holder, $method),
                    $arguments);
    }     /**
     * Reading Agent Member Attributes
     *
     * @param string $property
     * @throws ErrorException
     * @return mixed
     */
    public function __get($property)
    {
            $this->check();             if (!isset($this->holder->$property)) {
                    throw new ErrorException();
            }             return $this->holder->$property;
    }     /**
     * Assignment of Agent Member Attributes
     *
     * @param string $property
     * @param mixed  $value
     */
    public function __set($property, $value)
    {
            $this->check();             $this->holder->$property = $value;
    }     /**
     * Check whether the proxy object already exists, and generate if it does not exist.
     */
    private function check()
    {
            if (null == $this->holder) {
                    $loader = $this->loader;
                    $this->holder = $loader();
            }
    }
}
// Test
$v = new VirtualProxy(function(){
        echo 'Now, Loading', "\n";
    $a = new ArrayObject(range(1,100));
    $a->abc = 'a';
        // In actual use, what is called here is DataMapper Adj. findXXX Method
        // Returns a collection of domain objects
    return $a;
});
// The proxy object is accessed directly as the original object
// At this time, the passed in by the constructor callback Function is called
// So as to realize the delay of loading object operation
echo $v->abc . $v->offsetGet(50);


Related articles: