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 相关文章推荐
为查询结果建立向后/向前按钮
Oct 09 PHP
php fsockopen中多线程问题的解决办法[翻译]
Nov 09 PHP
thinkPHP实现表单自动验证
Dec 24 PHP
PHP微信开发之微信消息自动回复下所遇到的坑
May 09 PHP
PHP入门教程之图像处理技巧分析
Sep 11 PHP
php版微信公众平台开发之验证步骤实例详解
Sep 23 PHP
php连接微软MSSQL(sql server)完全攻略
Nov 27 PHP
PHP利用正则表达式将相对路径转成绝对路径的方法示例
Feb 28 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
Sep 20 PHP
thinkphp5 migrate数据库迁移工具
Feb 20 PHP
laravel5.6 框架邮件队列database驱动简单demo示例
Jan 26 PHP
PHP实现单例模式建立数据库连接的方法分析
Feb 11 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
JS与PHP向函数传递可变参数的区别实例代码
2011/05/18 PHP
php入门学习知识点六 PHP文件的读写操作代码
2011/07/14 PHP
PHP脚本监控Nginx 502错误并自动重启php-fpm
2015/05/13 PHP
详解PHP的Laravel框架中Eloquent对象关系映射使用
2016/02/26 PHP
PHP使用OB缓存实现静态化功能示例
2019/03/23 PHP
PHP+MySQL实现在线测试答题实例
2020/01/02 PHP
js下用gb2312编码解码实现方法
2009/12/31 Javascript
初试jQuery EasyUI 使用介绍
2010/04/01 Javascript
node.js 一个简单的页面输出实现代码
2012/03/07 Javascript
js不能跳转到上一页面的问题解决方法
2013/03/01 Javascript
jquery的live使用注意事项
2014/02/18 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
jQuery带时间的日期控件代码分享
2015/08/26 Javascript
jquery动态创建div与input的实例代码
2016/10/12 Javascript
给easyui datebox扩展一个清空的实例
2016/11/09 Javascript
vue实现页面加载动画效果
2017/09/19 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
2017/11/10 jQuery
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
微信小程序实现日历效果
2018/12/28 Javascript
layui下拉框获取下拉值(select)的例子
2019/09/10 Javascript
在 Vue 中编写 SVG 图标组件的方法
2020/02/24 Javascript
Python实现将DOC文档转换为PDF的方法
2015/07/25 Python
PyQt5每天必学之带有标签的复选框
2018/04/19 Python
django删除表重建的实现方法
2019/08/28 Python
TensorFlow 显存使用机制详解
2020/02/03 Python
UGG雪地靴德国官网:UGG德国
2016/11/19 全球购物
WoolOvers爱尔兰:羊绒、羊毛和棉针织品
2017/01/04 全球购物
网吧收银员岗位职责
2013/12/14 职场文书
医药销售自荐书
2014/05/29 职场文书
科级干部群众路线教育实践活动个人对照检查材料
2014/09/19 职场文书
公证书格式
2015/01/23 职场文书
故宫英文导游词
2015/01/31 职场文书
世界遗产导游词
2015/02/13 职场文书
公司庆典主持词
2015/07/04 职场文书
2016年三八节红领巾广播稿
2015/12/17 职场文书
Nginx反向代理多个服务器的实现方法
2021/03/31 Servers