加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php中通过虚代理实现延迟加载的实现代码

发布时间:2020-12-13 05:54:55 所属栏目:PHP教程 来源:网络整理
导读:这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载(LazyLoad)。基本原理是通过一个虚代理(Virtual Proxy)做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。 不过我实

这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载(LazyLoad)。基本原理是通过一个虚代理(Virtual Proxy)做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。 不过我实现的这个版本有局限性: 只适用于对象,无法代理数组等基本数据类型(需要用 ArrayObject 一类的内置对象封装)
被代理之后,一些带有操作符重载性质的接口实现就失效了,例如 ArrayAccess 的索引器、Itreator 的迭代器,如果是用该代理来处理集合类型的延迟加载,还需要继承一个子类做特殊处理,以便外部用 foreach 迭代
demo
<div class="codetitle"><a style="CURSOR: pointer" data="55489" class="copybut" id="copybut55489" onclick="doCopy('code55489')"> 代码如下:<div class="codebody" id="code55489">
// 测试
$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
<div class="codetitle"><a style="CURSOR: pointer" data="47203" class="copybut" id="copybut47203" onclick="doCopy('code47203')"> 代码如下:<div class="codebody" id="code47203">
/
虚代理,只有在被访问成员时才调用闭包函数生成目标对象。

@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();
}
}
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读