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的引用计数机制
Jun 14 PHP
win7计划任务定时执行PHP脚本设置图解
May 09 PHP
PHP 面向对象程序设计(oop)学习笔记(三) - 单例模式和工厂模式
Jun 12 PHP
JavaScript创建命名空间的5种写法
Jun 24 PHP
php针对cookie操作的队列操作类实例
Dec 10 PHP
详细解读PHP的Yii框架中登陆功能的实现
Aug 21 PHP
PHP类型约束用法示例
Sep 28 PHP
php 函数使用可变数量的参数方法
May 02 PHP
php分页查询mysql结果的base64处理方法示例
May 18 PHP
PHP生成短网址的思路以及实现方法的详解
Mar 25 PHP
php集成开发环境详解
Sep 24 PHP
ThinkPHP5.1验证码功能实现的示例代码
Jun 08 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中利用XML技术构造远程服务(下)
2006/10/09 PHP
PHP使用递归方式列出当前目录下所有文件的方法
2015/06/02 PHP
Yii框架用户登录session丢失问题解决方法
2017/01/07 PHP
thinkphp诸多限制条件下如何getshell详解
2020/12/09 PHP
Ext第一周 史上最强学习笔记---GridPanel(基础篇)
2008/12/29 Javascript
JavaScript 对象模型 执行模型
2010/10/15 Javascript
jquery中文乱码的多种解决方法
2013/06/21 Javascript
JS循环遍历JSON数据的方法
2014/07/08 Javascript
JavaScript如何一次性展示几万条数据
2017/03/30 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
Vue父子模版传值及组件传值的三种方法
2017/11/27 Javascript
详解vue-router数据加载与缓存使用总结
2018/10/29 Javascript
跨域解决之JSONP和CORS的详细介绍
2018/11/21 Javascript
vue实现密码显示与隐藏按钮的自定义组件功能
2019/04/23 Javascript
layui输入框中只允许输入整数的实现方法
2019/09/18 Javascript
js实现二级联动简单实例
2020/01/11 Javascript
python pandas dataframe 按列或者按行合并的方法
2018/04/12 Python
Python实现对文件进行单词划分并去重排序操作示例
2018/07/10 Python
flask session组件的使用示例
2018/12/25 Python
pycharm配置pyqt5-tools开发环境的方法步骤
2019/02/11 Python
画pytorch模型图,以及参数计算的方法
2019/08/17 Python
python判断链表是否有环的实例代码
2020/01/31 Python
django在开发中取消外键约束的实现
2020/05/20 Python
python删除文件、清空目录的实现方法
2020/09/23 Python
详解matplotlib绘图样式(style)初探
2021/02/03 Python
CSS3 Calc实现滚动条出现页面不跳动问题
2017/09/14 HTML / CSS
HTML5+CSS3应用详解
2014/02/24 HTML / CSS
世界上最好的儿童品牌:AlexandAlexa
2018/01/27 全球购物
PHP如何调用MYSQL存储过程
2014/05/30 面试题
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
活动总结怎么写
2014/04/28 职场文书
护士求职信
2014/07/05 职场文书
庆祝国庆节演讲稿2014
2014/09/19 职场文书
2014年审计人员工作总结
2014/12/19 职场文书
2015年乡镇残联工作总结
2015/05/13 职场文书
win10更新失败无限重启解决方法
2022/04/19 数码科技