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 相关文章推荐
在PHP3中实现SESSION的功能(一)
Oct 09 PHP
用PHP实现的生成静态HTML速度快类库
Mar 31 PHP
php 魔术方法使用说明
Oct 20 PHP
apache+php+mysql安装配置方法小结
Aug 01 PHP
php下尝试使用GraphicsMagick的缩略图功能
Jan 01 PHP
php中一个完整表单处理实现代码
Nov 10 PHP
PHP字符串函数系列之nl2br(),在字符串中的每个新行 (\n) 之前插入 HTML 换行符br
Nov 10 PHP
php实现自动获取生成文章主题关键词功能的深入分析
Jun 03 PHP
php实现查看邮件是否已被阅读的方法
Dec 03 PHP
laravel 4安装及入门图文教程
Oct 29 PHP
ThinkPHP表单令牌错误的相关解决方法分析
May 20 PHP
Laravel框架集合用法实例浅析
May 14 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
Oracle 常见问题解答
2006/10/09 PHP
php 网上商城促销设计实例代码
2012/02/17 PHP
解决Yii2邮件发送结果返回成功,但接收不到邮件的问题
2017/05/23 PHP
javascript获得服务器端控件的ID的实现代码
2011/12/28 Javascript
ejs v9 javascript模板系统
2012/03/21 Javascript
JavaScript中统计Textarea字数并提示还能输入的字符
2014/06/10 Javascript
js树插件zTree获取所有选中节点数据的方法
2015/01/28 Javascript
JS实现的页面自定义滚动条效果
2015/10/26 Javascript
值得分享的轻量级Bootstrap Table表格插件
2016/05/30 Javascript
Vue2学习笔记之请求数据交互vue-resource
2017/02/23 Javascript
jQuery手风琴的简单制作
2017/05/12 jQuery
Angular.js实现获取验证码倒计时60秒按钮的简单方法
2017/10/18 Javascript
js中的 || 与 && 运算符详解
2018/05/24 Javascript
如何在js代码中消灭for循环实例详解
2018/07/29 Javascript
ES6 中可以提升幸福度的小功能
2018/08/06 Javascript
Vue动态创建注册component的实例代码
2019/06/14 Javascript
JS代码优化的8点建议
2020/02/04 Javascript
Python3中使用urllib的方法详解(header,代理,超时,认证,异常处理)
2016/09/21 Python
Python错误: SyntaxError: Non-ASCII character解决办法
2017/06/08 Python
基于python检查SSL证书到期情况代码实例
2020/04/04 Python
python实现五子棋程序
2020/04/24 Python
Selenium关闭INFO:CONSOLE提示的解决
2020/12/07 Python
CSS3属性background-size使用指南
2014/12/09 HTML / CSS
美国生日蛋糕店:Bake Me A Wish!
2017/02/08 全球购物
美国零售商店:Blue&Cream
2017/04/07 全球购物
Ooni英国官网:披萨烤箱
2020/05/31 全球购物
英语老师推荐信
2014/02/26 职场文书
周年庆典主持词
2014/04/02 职场文书
销售提升方案
2014/06/07 职场文书
个人租房协议书范本
2014/09/30 职场文书
小学语文教师年度考核个人总结
2015/02/05 职场文书
物业工程部经理岗位职责
2015/04/09 职场文书
2016年大学生就业指导课心得体会
2015/10/09 职场文书
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
2021/05/26 Servers
Python爬虫中urllib3与urllib的区别是什么
2021/07/21 Python
Python学习之异常中的finally使用详解
2022/03/16 Python