This article describes how to use virtual proxy in PHP to implement delayed loading. Delayed loading is a domain model design architecture model, you can refer to this article from Martin's Enterprise Application Architecture model to assist with the dynamic language features of PHP, it is much easier to implement delayed loading than Java-by using a virtual proxy placeholder. The only defect is that only proxy objects are allowed, and basic types cannot be built into the proxy.
In the PHP domain model design I tried to use this to implement delayed loading of DomainObject.
The code is as follows:
* Virtual proxy: The closure function is called only when the Accessed member is used to generate the target object.
*
* @ Author tonyseek
*
*/
Class VirtualProxy
{
Private $ holder = null;
Private $ loader = null;
/**
* Virtual proxy: The closure function is called only when the Accessed member is used to generate the target object.
*
* @ Param Closure $ loader generates the Closure function of the proxy object
*/
Public function _ construct (Closure $ loader)
{
$ This-> loader = $ loader;
}
/**
* Call of proxy member methods
*
* @ 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 );
}
/**
* Read proxy 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;
}
/**
* Value assignment of proxy member attributes
*
* @ Param string $ property
* @ Param mixed $ value
*/
Public function _ set ($ property, $ value)
{
$ This-> check ();
$ This-> holder-> $ property = $ value;
}
/**
* Check whether a proxy object already exists. If no proxy object exists, it is generated.
*/
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, the findXXX method of DataMapper is called here
// The returned result is a collection of domain objects.
Return $;
});
// The proxy object is directly accessed as the original object
// At this time, the callback function passed in by the constructor is called.
// Delay in object loading
Echo $ v-> abc. $ v-> offsetGet (50 );