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 相关文章推荐
php MYSQL 数据备份类
Jun 19 PHP
php csv操作类代码
Dec 14 PHP
基于php设计模式中单例模式的应用分析
May 15 PHP
PHP管理依赖(dependency)关系工具 Composer 安装与使用
Aug 18 PHP
php中explode的负数limit用法分析
Feb 27 PHP
php实现的用户查询类实例
Jun 18 PHP
PHP封装的数据库保存session功能类
Jul 11 PHP
PHP获取当前执行php文件名的代码
Mar 02 PHP
解决laravel 5.1报错:No supported encrypter found的办法
Jun 07 PHP
使用PHP访问RabbitMQ消息队列的方法示例
Jun 06 PHP
php实现通过stomp协议连接ActiveMQ操作示例
Feb 23 PHP
laravel入门知识点整理
Sep 15 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
PHP调用三种数据库的方法(3)
2006/10/09 PHP
实用函数9
2007/11/08 PHP
PHP中$_FILES的使用方法及注意事项说明
2014/02/14 PHP
Smarty模板学习笔记之Smarty简介
2014/05/20 PHP
PHP把JPEG图片转换成Progressive JPEG的方法
2014/06/30 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
2016/09/11 PHP
PHP静态成员变量和非静态成员变量详解
2017/02/14 PHP
php基于数组函数实现关联表的编辑操作示例
2017/07/04 PHP
php成功操作redis cluster集群的实例教程
2019/01/13 PHP
PHP开发实现快递查询功能详解
2019/04/08 PHP
Laravel模糊查询区分大小写的实例
2019/09/29 PHP
JavaScript高级程序设计(第3版)学习笔记5 js语句
2012/10/11 Javascript
Extjs 3.3切换tab隐藏相应工具栏出现空白解决
2013/04/02 Javascript
js opener的使用详解
2014/01/11 Javascript
JavaScript新窗口与子窗口传值详解
2014/02/11 Javascript
JavaScript中利用Array和Object实现Map的方法
2015/07/27 Javascript
JS中Array数组学习总结
2017/01/18 Javascript
Vue.js:使用Vue-Router 2实现路由功能介绍
2017/02/22 Javascript
详解Angular CLI + Electron 开发环境搭建
2017/07/20 Javascript
如何用input标签和jquery实现多图片的上传和回显功能
2018/05/16 jQuery
vue组件实践之可搜索下拉框功能
2018/11/25 Javascript
一文了解vue-router之hash模式和history模式
2019/05/31 Javascript
Vue中消息横向滚动时setInterval清不掉的问题及解决方法
2019/08/23 Javascript
Python中defaultdict与lambda表达式用法实例小结
2018/04/09 Python
PyCharm专业最新版2019.1安装步骤(含激活码)
2019/10/09 Python
tensorflow模型保存、加载之变量重命名实例
2020/01/21 Python
Django设置Postgresql的操作
2020/05/14 Python
Django如何在不停机的情况下创建索引
2020/08/02 Python
数百万免费的图形资源:Freepik
2020/09/21 全球购物
应届毕业生求职信范文分享
2013/12/26 职场文书
建筑个人求职信范文
2014/01/25 职场文书
化妆品店促销方案
2014/02/24 职场文书
质量承诺书范文
2014/03/27 职场文书
团队经理竞聘书
2014/03/31 职场文书
优秀大专毕业生求职信
2014/08/04 职场文书
假如给我三天光明:舟逆水而行,人遇挫而达 
2019/10/29 职场文书