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


Posted in PHP onJune 10, 2011

这货是从 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 相关文章推荐
CodeIgniter中使用cookie的三种方式详解
Jul 18 PHP
php实现设计模式中的单例模式详解
Oct 11 PHP
THINKPHP内容分页代码分享
Jan 14 PHP
php实现按天数、星期、月份查询的搜索框
May 02 PHP
Yii2中关联查询简单用法示例
Aug 10 PHP
遍历echsop的region表形成缓存的程序实例代码
Nov 01 PHP
php对微信支付回调处理的方法
Aug 23 PHP
PHP压缩图片功能的介绍
Mar 21 PHP
PHP利用递归函数实现无限级分类的方法
Mar 22 PHP
php和C#的yield迭代器实现方法对比分析
Jul 17 PHP
Laravel框架实现文件上传的方法分析
Sep 29 PHP
PHP中用Trait封装单例模式的实现
Dec 18 PHP
php获取后台Job管理的实现代码
Jun 10 #PHP
php下通过curl抓取yahoo boss 搜索结果的实现代码
Jun 10 #PHP
PHP缩略图等比例无损压缩,可填充空白区域补充色
Jun 10 #PHP
PHP网站备份程序代码分享
Jun 10 #PHP
php在页面中调用fckeditor编辑器的方法
Jun 10 #PHP
PHP中遍历stdclass object的实现代码
Jun 09 #PHP
IIS7.X配置PHP运行环境小结
Jun 09 #PHP
You might like
分享一个超好用的php header下载函数
2014/01/31 PHP
浅谈ThinkPHP的URL重写
2014/11/25 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
js封装的textarea操作方法集合(兼容很好)
2010/11/16 Javascript
Javascript 静态页面实现随机显示广告的办法
2010/11/17 Javascript
JS Jquery 遍历,筛选页面元素 自动完成(实现代码)
2013/07/08 Javascript
js代码实现无缝滚动(文字和图片)
2015/08/20 Javascript
通过隐藏iframe实现无刷新上传文件操作
2016/03/16 Javascript
Bootstrap+jfinal实现省市级联下拉菜单
2016/05/30 Javascript
AngularJS入门教程之迭代器过滤详解
2016/08/18 Javascript
jquery弹出框插件jquery.ui.dialog用法分析
2016/08/20 Javascript
jquery实现input框获取焦点的简单实例
2017/01/26 Javascript
Javascript中引用类型传递的知识点小结
2017/03/06 Javascript
浅谈vuex之mutation和action的基本使用
2017/08/29 Javascript
Nodejs实现多文件夹文件同步
2018/10/17 NodeJs
Node 代理访问的实现
2019/09/19 Javascript
JavaScript实现烟花绽放动画效果
2020/08/04 Javascript
vue3自定义dialog、modal组件的方法
2021/01/04 Vue.js
python通过pil模块将raw图片转换成png图片的方法
2015/03/16 Python
python利用paramiko连接远程服务器执行命令的方法
2017/10/16 Python
Python面向对象编程基础解析(一)
2017/10/26 Python
Python绘制3D图形
2018/05/03 Python
Python爬虫基础之XPath语法与lxml库的用法详解
2018/09/13 Python
python自动化工具之pywinauto实例详解
2019/08/26 Python
Tensorflow tf.nn.depthwise_conv2d如何实现深度卷积的
2020/04/20 Python
VSCode配合pipenv搞定虚拟环境的实现方法
2020/05/17 Python
意大利综合购物网站:Giordano Shop
2016/10/21 全球购物
如何获得EntityManager
2014/02/09 面试题
思想品德自我评价
2014/02/04 职场文书
《我的信念》教学反思
2014/02/15 职场文书
事业单位考核材料
2014/05/21 职场文书
公司演讲稿开场白
2014/08/25 职场文书
我与祖国共奋进演讲稿
2014/09/13 职场文书
小学教师党员承诺书
2015/04/27 职场文书
八年级语文教学反思
2016/03/03 职场文书
关于Python OS模块常用文件/目录函数详解
2021/07/01 Python