频道直达 - 专题 - 新闻 - 基础 - 高级 - 安装 - 技巧 - 数据库 - 手册 - PHP - Linux - Java - MySQL - Apache - 麻辣堂 - 狼盟 - Rails社群 - 搜索 - 下载 - 开源 - 论坛
PHP开发资源网 主页>>PHP基础教程>> 收藏此文 | 收藏本站 | 设为首页

实现php的动态代理

来源:www.phpres.com 作者:Angelover 出处:www.phpres.com 2008-6-28 09:56:39 进入讨论组
关 键 词: 代理 动态 实现 c-foo class echo property function

                 本来php4里,在对象内部是可以对$this赋值的(或许是bug)。但php5不让这样了,如果对$this赋值会引发一个fatel error:can not re-asign to $this。今天突然想到了一个办法。既然不让对$this赋值,那能不能绕个圈实现呢?
运行一下下面的代码
<?php
class Container {
    public $foo;
    function __construct() {
        $this->foo=new Proxy($this);
    }
}
class Proxy {
    private $container;
    function __construct(&amp;$container) {
        $this->container=$container;
    }
    function go() {
        $this->container->foo=10;
    }
}
$c=new Container;
echo "开始\n";
echo 'gettype($c->foo) = \''.gettype($c->foo)."'\n";
echo 'get_class($c->foo) = \''.get_class($c->foo)."'\n";
echo "然后\n";
$c->foo->go();
echo 'gettype($c->foo) = \''.gettype($c->foo)."'\n";
echo '$c->foo = '.$c->foo."\n";
?>
结果是:

开始
gettype($c->foo) = 'object'
get_class($c->foo) = 'Proxy'
然后
gettype($c->foo) = 'integer'
$c->foo = 10

可以看到,$c->foo已经从一个Proxy对象变成了一个整数,而这一切是在对象内部完成的。这样,我们就可以做一个清爽的动态代理了。

class Container {
    var $p;
    function __construct() {
        $this->p=new Proxy($this,'p','Target');
    }
}

class Target {
    var $v=777;
}

class Proxy {
    private $container;
    private $property;
    private $className;
    function __construct(&amp;$container, $property, $class) {
        $this->container=&amp;$container;
        $this->property=$property;
        $this->className=$class;
    }

    function __get($key) {
        $class=$this->className;
        $obj=new $class;
        $property=$this->property;
        $this->container->$property=$obj;
        return $obj->$key;
    }

    function __call($func, $arg) {
        $class=$this->className;
        $obj=new $class;
        $property=$this->property;
        $this->container->$property=$obj;
        return call_user_func_array(array($obj,$func), $arg);
    }
}

$c=new Container;
echo get_class($c->p)."\n";
echo $c->p->v."\n";
echo get_class($c->p)."\n";
echo $c->p->v."\n";
可以看到,使用代理和使用实际对象没有区别,而且当第二次访问的时候,$c->p已经变成了实际的对象了。欢迎进入PHP开发资源论坛讨论。
收藏此文】【 】【打印】【关闭
相关文章
图文推荐
论 坛 资 源
PHP开发资源网奋斗目标
阅读排行:
热门技术文档
最新图文档
本站编辑推荐:(本站开通Delphi4PHP专区,欢迎进入论坛交流!)
编缉最近更新文章
网站赞助商
搜索您感兴趣的内容
 
   网站首页 -  网站地图 -  网站合作 -  手册中心 -  通用网址 -  网站论坛 -  网站投稿 -  友情链接 -  帮助中心
版权所有:PHP开发资源网 © 2003-2008 通用网址:PHP资源网 合作媒体: 赛迪网IT技术
互联网违法和不良信息举报中心 | 不良信息举报信箱