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);