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环境搭建最新方法
Sep 05 PHP
中国站长站 For Dede4.0 采集规则
May 27 PHP
php图片验证码代码
Mar 27 PHP
phpmail类发送邮件函数代码
Feb 20 PHP
深入array multisort排序原理的详解
Jun 18 PHP
解析PHP中empty is_null和isset的测试
Jun 29 PHP
CentOS安装php v8js教程
Feb 26 PHP
提高php编程效率技巧
Aug 13 PHP
php实现的mysqldb读写分离操作类示例
Feb 07 PHP
php实现微信支付之企业付款
May 30 PHP
php的无刷新操作实现方法分析
Feb 28 PHP
laravel中Redis队列监听中断的分析
Sep 14 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
超级简单的发送邮件程序
2006/10/09 PHP
PHP 循环列出目录内容的函数代码
2010/05/26 PHP
php随机抽奖实例分析
2015/03/04 PHP
Aster vs Newbee BO3 第三场2.18
2021/03/10 DOTA
jQuery 入门级学习笔记及源码
2010/01/22 Javascript
jQuery 获取对象 定位子对象
2010/05/31 Javascript
jquery.blockUI.js上传滚动等待效果实现思路及代码
2013/03/18 Javascript
jQuery制作仿腾讯web qq用户体验桌面
2013/08/20 Javascript
jQuery中delegate和on的用法与区别详细解析
2014/01/26 Javascript
JS获取时间的方法
2015/01/21 Javascript
基于jQuey实现鼠标滑过变色(整行变色)
2015/12/07 Javascript
详解js跨域原理以及2种解决方案
2015/12/09 Javascript
AngularJs Scope详解及示例代码
2016/09/01 Javascript
关于Jquery中的事件绑定总结
2016/10/26 Javascript
网络传输协议(http协议)
2016/11/18 Javascript
jQuery树控件zTree使用方法详解(一)
2017/02/28 Javascript
详解react-router 4.0 下服务器如何配合BrowserRouter
2017/12/29 Javascript
JS获取今天是本月第几周、本月共几周、本月有多少天、是今年的第几周、是今年的第几天的示例代码
2018/12/05 Javascript
微信小程序和H5页面间相互跳转代码实例
2019/09/19 Javascript
使用zrender.js绘制体温单效果
2019/10/31 Javascript
解决vue打包报错Unexpected token: punc的问题
2020/10/24 Javascript
[39:00]Optic vs VP 2018国际邀请赛淘汰赛BO3 第三场 8.24
2018/08/25 DOTA
进一步理解Python中的函数编程
2015/04/13 Python
pycharm远程开发项目的实现步骤
2019/01/20 Python
python+mysql实现个人论文管理系统
2019/10/25 Python
Python实现图像的垂直投影示例
2020/01/17 Python
利用pipenv和pyenv管理多个相互独立的Python虚拟开发环境
2020/11/01 Python
全方位了解CSS3的Regions扩展
2015/08/07 HTML / CSS
HTML5 与 XHTML2
2008/10/17 HTML / CSS
HTML5+css3:3D旋转木马效果相册
2017/01/03 HTML / CSS
e路東瀛(JAPANiCAN)香港:日本旅游、日本酒店和温泉旅馆预订
2018/11/21 全球购物
专业毕业生个性的自我评价
2013/10/03 职场文书
母亲节演讲稿范文
2014/01/02 职场文书
春季运动会广播稿大全
2014/02/19 职场文书
初中生300字旷课检讨书
2014/11/19 职场文书
大学生读书笔记大全
2015/07/01 职场文书