php中通过虚代理实现延迟加载的实现代码
2015-01-24信息快讯网
基本原理是通过一个虚代理(Virtual Proxy)做占位符,一旦访问代理对象的某成员(方法或属性),加载就被触发。
这货是从 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延迟静态绑定示例分享
PHP 面向对象程序设计(oop)学习笔记 (二) - 静态变量的属性和方法及延迟绑定
php教程 插件机制在PHP中实现方案
用php实现百度网盘图片直链的代码分享
php中将指针移动到数据集初始位置的实现代码[mysql_data_seek]
php图片加中文水印实现代码分享
PHP 万年历实现代码
说说PHP的autoLoad自动加载机制
php在线代理转向代码
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
php _autoload自动加载类与机制分析
php 无法加载mysql的module的时候的配置的解决方案引发的思考
PHP spl_autoload_register实现自动加载研究
php设计模式 Proxy (代理模式)
php中使用Akismet防止垃圾评论的代码
php获取后台Job管理的实现代码
php下通过curl抓取yahoo boss 搜索结果的实现代码
PHP中遍历stdclass object的实现代码
php学习之流程控制实现代码
php学习之简单计算器实现代码
PHP下通过file_get_contents的代理使用方法
PHP的autoload自动加载机制使用说明
php include加载文件两种方式效率比较
php自动加载的两种实现方法
人社部:延迟退休应"先女后男" 渐进推行
专家:延迟退休应“先女后男”
延迟退休需“小步徐行”
延迟退休需“小步徐行”