php的动态代理的又一种实现

jackxiang 2010-3-17 16:42 | |

                 本来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($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已经变成了实际的对象了。
来源:http://syre.blogbus.com/logs/1882118.html

作者:jackxiang@向东博客 专注WEB应用 构架之美 --- 构架之美,在于尽态极妍 | 应用之美,在于药到病除
地址:https://jackxiang.com/post/2832/
版权所有。转载时必须以链接形式注明作者和原始出处及本声明!


最后编辑: jackxiang 编辑于2010-3-17 16:57
评论列表
发表评论

昵称

网址

电邮

打开HTML 打开UBB 打开表情 隐藏 记住我 [登入] [注册]