Home  >  Article  >  Backend Development  >  How to implement lazy loading through virtual proxy in php

How to implement lazy loading through virtual proxy in php

不言
不言Original
2018-06-21 11:55:161549browse

This article mainly introduces how to implement delayed loading through virtual proxy in PHP. It has certain reference value. Now I share it with you. Friends in need can refer to it.

The basic principle is to use a virtual proxy to achieve lazy loading. The proxy (Virtual Proxy) is used as a placeholder. Once a member (method or property) of the proxy object is accessed, the loading is triggered.

This thing was learned from Martin's "Enterprise Application Architecture Patterns". It assists the characteristics of PHP dynamic language and can implement lazy loading (LazyLoad) much easier than Java. The basic principle is to use a virtual proxy (Virtual Proxy) as a placeholder. Once a member (method or attribute) of the proxy object is accessed, the loading is triggered.
However, the version I implemented has limitations:
It is only applicable to objects and cannot proxy basic data types such as arrays (it needs to be encapsulated with built-in objects such as ArrayObject)
After being proxied, some operations The interface implementation with the overloaded nature of the symbol becomes invalid, such as the indexer of ArrayAccess and the iterator of Itreator. If the proxy is used to handle the delayed loading of collection types, a subclass needs to be inherited for special processing so that external foreach iteration can be used

// 测试 
$v = new VirtualProxy(function(){ 
echo 'Now, Loading', "\n"; 
$a = new ArrayObject(range(1,100)); 
$a->abc = 'a'; 
// 实际使用中,这里调用的是 DataMapper 的 findXXX 方法 
// 返回的是领域对象集合 
return $a; 
}); 
// 代理对象直接当作原对象访问 
// 而此时构造方法传入的 callback 函数才被调用 
// 从而实现加载对象操作的延迟 
echo $v->abc . $v->offsetGet(50);

Virtual Proxy

/** 
* 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 
* 
* @author tonyseek 
* 
*/ 
class VirtualProxy 
{ 
private $holder = null; 
private $loader = null; 

/** 
* 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。 
* 
* @param Closure $loader 生成被代理对象的闭包函数 
*/ 
public function __construct(Closure $loader) 
{ 
$this->loader = $loader; 
} 

/** 
* 代理成员方法的调用 
* 
* @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); 
} 

/** 
* 代理成员属性的读取 
* 
* @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; 
} 

/** 
* 代理成员属性的赋值 
* 
* @param string $property 
* @param mixed $value 
*/ 
public function __set($property, $value) 
{ 
$this->check(); 

$this->holder->$property = $value; 
} 

/** 
* 检查是否已经存在被代理对象,不存在则生成。 
*/ 
private function check() 
{ 
if (null == $this->holder) { 
$loader = $this->loader; 
$this->holder = $loader(); 
} 
} 
}

The above is the entire content of this article. I hope it will be helpful to everyone's study. For more related content, please pay attention to the PHP Chinese website!

Related recommendations:

About the analysis of the urlencode() URL encoding function in PHP

How to use PHP to solve the problem of large website Traffic and high concurrency issues

#PHP Analysis of 2 sets of configuration files and parameters of APC

The above is the detailed content of How to implement lazy loading through virtual proxy in php. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn