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 伪造本地文件包含漏洞的代码
Nov 03 PHP
深入php多态的实现详解
Jun 09 PHP
基于PHP实现数据分页显示功能
May 26 PHP
Laravel 5.3 学习笔记之 错误&日志
Aug 28 PHP
PHP获取input输入框中的值去数据库比较显示出来
Nov 16 PHP
Thinkphp框架中D方法与M方法的区别
Dec 23 PHP
PHP+Ajax无刷新带进度条图片上传示例
Feb 08 PHP
Zend Framework基于Command命令行建立ZF项目的方法
Feb 18 PHP
php实现保存周期为1天的购物车类
Jul 07 PHP
源码分析 Laravel 重复执行同一个队列任务的原因
Dec 25 PHP
php+redis实现商城秒杀功能
Nov 19 PHP
php curl发送请求实例方法
Aug 01 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模板,主要想体现一下思路
2006/12/25 PHP
PHP全局变量与超级全局变量区别分析
2016/04/01 PHP
php curl获取到json对象并转成数组array的方法
2018/05/31 PHP
PHP代码覆盖率统计详解
2020/07/22 PHP
Prototype使用指南之string.js
2007/01/10 Javascript
分享27款非常棒的jQuery 表单插件
2011/03/28 Javascript
jQuery照片伸缩效果不影响其他元素的布局
2014/05/09 Javascript
DEDECMS如何为文章添加HOT NEW标志图片
2015/08/14 Javascript
jQuery实现气球弹出框式的侧边导航菜单效果
2015/09/22 Javascript
JS模拟酷狗音乐播放器收缩折叠关闭效果代码
2015/10/29 Javascript
浅谈使用splice函数对数组中的元素进行删除时的注意事项
2016/12/04 Javascript
JS优化与惰性载入函数实例分析
2017/04/06 Javascript
Layui table 组件的使用之初始化加载数据、数据刷新表格、传参数
2017/09/11 Javascript
Vue 组件注册实例详解
2019/02/23 Javascript
详解mpvue中使用vant时需要注意的onChange事件的坑
2019/05/16 Javascript
angularjs模态框的使用代码实例
2019/12/20 Javascript
Vue 解决在element中使用$notify在提示信息中换行问题
2020/11/11 Javascript
[08:06]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Elephant 选手采访
2021/03/11 DOTA
Python ORM框架SQLAlchemy学习笔记之数据查询实例
2014/06/10 Python
Ubuntu 14.04+Django 1.7.1+Nginx+uwsgi部署教程
2014/11/18 Python
Python定义二叉树及4种遍历方法实例详解
2018/07/05 Python
python opencv实现图片旋转矩形分割
2018/07/26 Python
Python编写合并字典并实现敏感目录的小脚本
2019/02/26 Python
详解PyTorch中Tensor的高阶操作
2019/08/18 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
Python正则表达式急速入门(小结)
2019/12/16 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
如何使用Django Admin管理后台导入CSV
2020/11/06 Python
英国家居用品和床上用品零售商:P&B Home
2020/01/16 全球购物
小区门卫值班制度
2014/01/24 职场文书
个人现实表现材料
2014/02/04 职场文书
医疗器械售后服务承诺书
2014/05/21 职场文书
最美家庭活动方案
2014/08/31 职场文书
2014年党小组工作总结
2014/12/20 职场文书
演讲开头怎么书写?
2019/08/06 职场文书
原生JS封装vue Tab切换效果
2021/04/28 Vue.js