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

 更新时间:2011年06月10日 00:40:25   作者:  
基本原理是通过一个虚代理(Virtual Proxy)做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。
这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载(LazyLoad)。基本原理是通过一个虚代理(Virtual Proxy)做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。

不过我实现的这个版本有局限性:

只适用于对象,无法代理数组等基本数据类型(需要用 ArrayObject 一类的内置对象封装)
被代理之后,一些带有操作符重载性质的接口实现就失效了,例如 ArrayAccess 的索引器、Itreator 的迭代器,如果是用该代理来处理集合类型的延迟加载,还需要继承一个子类做特殊处理,以便外部用 foreach 迭代
demo
复制代码 代码如下:

// 测试
$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();
}
}
}

相关文章

  • php实现无限级分类(递归方法)

    php实现无限级分类(递归方法)

    当你学习php无限极分类的时候,大家都觉得一个字“难”我也觉得很难,所以,现在都还在看,因为工作要用到,所以,就必须得研究研究。
    2015-08-08
  • php字符串操作常见问题小结

    php字符串操作常见问题小结

    这篇文章主要介绍了php字符串操作常见问题,结合实例形式分析了php针对json的操作及字符串转换问题,需要的朋友可以参考下
    2016-10-10
  • php实现文件上传及头像预览功能

    php实现文件上传及头像预览功能

    这篇文章主要介绍了php实现文件上传及头像预览功能的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-01-01
  • 解析php中的fopen()函数用打开文件模式说明

    解析php中的fopen()函数用打开文件模式说明

    本篇文章是对php中的fopen()函数用打开文件模式说明进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • 详解php魔术方法(Magic methods)的使用方法

    详解php魔术方法(Magic methods)的使用方法

    有些东西如果不是经常使用,很容易忘记,比如魔术方法和魔术常量,这篇文章主要介绍了php魔术方法(Magic methods)的使用方法,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • php中用数组的方法设置cookies

    php中用数组的方法设置cookies

    php中用数组的方法设置cookies,需要的朋友可以参考下。
    2011-04-04
  • PHP中的Iterator迭代对象属性详解

    PHP中的Iterator迭代对象属性详解

    这篇文章主要给大家介绍了关于PHP中Iterator迭代对象属性的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用PHP具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-04-04
  • PHP使用Mysqli类库实现完美分页效果的方法

    PHP使用Mysqli类库实现完美分页效果的方法

    这篇文章主要介绍了PHP使用Mysqli类库实现完美分页效果的方法,结合实例形式分析了PHP使用Mysqli类库的相关配置文件设置,数据库操作及分页的相关实现技巧,需要的朋友可以参考下
    2016-04-04
  • php+ajax实现无刷新的新闻留言系统

    php+ajax实现无刷新的新闻留言系统

    这篇文章主要介绍了一款基于php+ajax无刷新的新闻留言系统实现过程,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2015-10-10
  • 举例讲解PHP面对对象编程的多态

    举例讲解PHP面对对象编程的多态

    这篇文章主要介绍了举例讲解PHP面对对象编程的多态,是PHP入门学习中的基础知识,需要的朋友可以参考下
    2015-08-08

最新评论