PHP中使用虚代理实现延迟加载技术


Posted in PHP onNovember 05, 2014

话说这货是从 Martin 大神的《企业应用架构模式》中学到的,辅助 PHP 动态语言的特性,可以比 Java 轻松很多的实现延迟加载——通过一个虚代理占位符。唯一的缺陷,是只能代理对象,不能代理内置基本类型。

我试水的 PHP 领域模型设计中,也是用这个来实现 DomainObject 的延迟加载。

 * 虚代理,只有在被访问成员时才调用闭包函数生成目标对象。

 *

 * @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();

            }

    }

}


// 测试

$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);
PHP 相关文章推荐
多文件上传的例子
Oct 09 PHP
用PHP连mysql和oracle数据库性能比较
Oct 09 PHP
PHP防注入安全代码
Apr 09 PHP
PHP 数组入门教程小结
May 20 PHP
php中如何判断一个网页请求是ajax请求还是普通请求
Aug 10 PHP
php7基于递归实现删除空文件夹的方法示例
Jun 15 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
Jul 03 PHP
如何通过View::first使用Laravel Blade的动态模板详解
Sep 21 PHP
如何通过View::first使用Laravel Blade的动态模板详解
Sep 21 PHP
PHP封装的XML简单操作类完整实例
Nov 13 PHP
PHP实现数组的笛卡尔积运算示例
Dec 15 PHP
php如何比较两个浮点数是否相等详解
Feb 12 PHP
PHP实现获取域名的方法小结
Nov 05 #PHP
php调用shell的方法
Nov 05 #PHP
PHP+Mysql实现多关键字与多字段生成SQL语句的函数
Nov 05 #PHP
ThinkPHP水印功能实现修复PNG透明水印并增加JPEG图片质量可调整
Nov 05 #PHP
phpnow php探针环境检测代码
Nov 04 #PHP
Thinkphp中volist标签mod控制一定记录的换行BUG解决方法
Nov 04 #PHP
ThinkPHP入库出现两次反斜线转义及数据库类转义的解决方法
Nov 04 #PHP
You might like
Windows Apache2.2.11及Php5.2.9-1的安装与配置方法
2009/06/08 PHP
Php中使用Select 查询语句的实例
2014/02/19 PHP
PHP封装的一个支持HTML、JS、PHP重定向的多功能跳转函数
2014/06/19 PHP
几道坑人的PHP面试题 试试看看你会不会也中招
2014/08/19 PHP
实例分析基于PHP微信网页获取用户信息
2017/11/24 PHP
如果文字过长,则将过长的部分变成省略号显示
2006/06/26 Javascript
Jquery 动态添加按钮实现代码
2010/05/06 Javascript
javascript制作loading动画效果 loading效果
2014/01/14 Javascript
什么是 AngularJS?AngularJS简介
2014/12/06 Javascript
深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP详解
2015/03/05 Javascript
js获取微信版本号的方法
2015/05/12 Javascript
JavaScript日期对象(Date)基本用法示例
2017/01/18 Javascript
js 事件的传播机制(实例讲解)
2017/07/20 Javascript
Angularjs渲染的 using 指令的星级评分系统示例
2017/11/09 Javascript
在微信小程序里使用watch和computed的方法
2018/08/02 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
Vue 中如何将函数作为 props 传递给组件的实现代码
2020/05/12 Javascript
Jquery Fade用法详解
2020/11/06 jQuery
python自动登录12306并自动点击验证码完成登录的实现源代码
2018/04/25 Python
tensorflow使用神经网络实现mnist分类
2018/09/08 Python
python使用socket实现的传输demo示例【基于TCP协议】
2019/09/24 Python
python使用itchat模块给心爱的人每天发天气预报
2019/11/25 Python
python 实现按对象传值
2019/12/26 Python
python实现提取str字符串/json中多级目录下的某个值
2020/02/27 Python
pycharm 关掉syntax检查操作
2020/06/09 Python
Python Django中间件使用原理及流程分析
2020/06/13 Python
在css3中background-clip属性与background-origin属性的用法介绍
2012/11/13 HTML / CSS
意大利时尚奢侈品店:D’Aniello Boutique
2021/01/19 全球购物
校庆标语集锦
2014/06/25 职场文书
2014年法院工作总结
2014/11/24 职场文书
人事专员岗位职责
2015/02/03 职场文书
2015年健康教育工作总结
2015/04/10 职场文书
傲慢与偏见读书笔记
2015/06/29 职场文书
python用tkinter开发的扫雷游戏
2021/06/01 Python
MySQL系列之三 基础篇
2021/07/02 MySQL
Redis之RedisTemplate配置方式(序列和反序列化)
2022/03/13 Redis