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 相关文章推荐
刚才在简化php的库,结果发现很多东西
Dec 31 PHP
php木马攻击防御之道
Mar 24 PHP
PHP 批量删除 sql语句
Jun 05 PHP
PHP 引用文件技巧
Mar 02 PHP
php中OR与|| AND与&&的区别总结
Oct 26 PHP
thinkphp实现数组分页示例
Apr 13 PHP
php中有关字符串的4个函数substr、strrchr、strstr、ereg介绍和使用例子
Apr 24 PHP
PHP函数in_array()使用详解
Aug 20 PHP
php中mt_rand()随机数函数用法
Nov 24 PHP
php使用Jpgraph绘制饼状图的方法
Jun 10 PHP
php简单判断两个字符串是否相等的方法
Jul 13 PHP
yii2.0整合阿里云oss的示例代码
Sep 19 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 Token(令牌)设计
2008/03/15 PHP
php将html转成wml的WAP标记语言实例
2015/07/08 PHP
PHP实现的统计数据功能详解
2016/12/06 PHP
PHP中有关长整数的一些操作教程
2019/09/11 PHP
PHP实现递归的三种方法
2020/07/04 PHP
js apply/call/caller/callee/bind使用方法与区别分析
2009/10/28 Javascript
JavaScript获取FCK编辑器信息的具体方法
2013/07/12 Javascript
js中浮点型运算BUG的解决方法说明
2014/01/06 Javascript
JS实现网页右侧带动画效果的伸缩窗口代码
2015/10/29 Javascript
js+ajax实现获取文件大小的方法
2015/12/08 Javascript
10分钟掌握XML、JSON及其解析
2020/12/06 Javascript
Node.js中如何合并两个复杂对象详解
2016/12/31 Javascript
利用Javascript实现简单的转盘抽奖
2017/02/13 Javascript
BootStrap+Mybatis框架下实现表单提交数据重复验证
2017/03/23 Javascript
用 Vue.js 递归组件实现可折叠的树形菜单(demo)
2017/12/25 Javascript
Vue的轮播图组件实现方法
2018/03/03 Javascript
JS+HTML实现的圆形可点击区域示例【3种方法】
2018/08/01 Javascript
微信小程序实现弹出层效果
2020/05/26 Javascript
vue自定义指令用法经典实例小结
2019/03/16 Javascript
vue实现codemirror代码编辑器中的SQL代码格式化功能
2019/08/27 Javascript
[02:36]DOTA2英雄基础教程 斯拉克
2013/11/29 DOTA
[03:48]2014DOTA2 TI专访71DK夺冠不靠小组赛高排名
2014/07/11 DOTA
[49:08]Secret vs VP 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python接收Gmail新邮件并发送到gtalk的方法
2015/03/10 Python
Python and、or以及and-or语法总结
2015/04/14 Python
jenkins+python自动化测试持续集成教程
2020/05/12 Python
python 从list中随机取值的方法
2020/11/16 Python
HTML5 canvas 瀑布流文字效果的示例代码
2018/01/31 HTML / CSS
美国著名的户外用品品牌:L.L.Bean
2018/01/05 全球购物
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
小孩百日宴答谢词
2014/01/15 职场文书
三年级评语大全
2014/04/23 职场文书
应用心理学专业求职信
2014/08/04 职场文书
学校证明范文
2015/06/24 职场文书
电频谱管理的原则是什么
2022/02/18 无线电
MySQL创建管理LIST分区
2022/04/13 MySQL