微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

php – 魔术吸气器/设定器未被调用

当我在Zend PHP认证考试指南5.5中阅读OOP章时,我发现一个问题让我感到震惊.这个问题是:
class Magic
{
    public $a = "A";
    protected $b = array( "a" => "A","b" => "B","c" => "C" );
    protected $c = array( 1,2,3 );

    public function __get( $v )
    {
        echo "$v";
        return $this->b[$v];
    }

    public function __set( $var,$val )
    {
        echo "$var: $val,";
        $this->$var = $val;
    }
}

$m = new Magic();
echo $m->a . "," . $m->b . "," . $m->c . ",";
$m->c = "CC";
echo $m->a . ",";

代码输出是:

b,c,A,B,C,c: CC,b,C

为什么这个代码不能打印出来,它是如何工作的?

__get仅针对不存在或不可见的属性进行调用.换句话说,当你写
$obj->prop

如果prop被定义并且在当前上下文中可见,则它将按原样返回,而不调用__get.

例:

class X {

    public   $pub = 1;
    private  $pri = 2;

    function __get($v) {
        echo "[get $v]\n";
        return 42;
    }

    function test() {
        echo $this->foo,"\n";  // __get invoked
        echo $this->pri,"\n";  // no __get
        echo $this->pub,"\n";  // no __get

    }
}

$x = new X;
$x->test();

echo $x->foo,"\n"; // __get invoked
echo $x->pri,"\n"; // __get invoked (property not visible)
echo $x->pub,"\n"; // no __get

这就解释了为什么magic-> a不调用吸气剂.现在,由于你也定义了setter,所以magic-> c = CC实际上改变了类的受保护成员,因此,当你稍后回覆magic-> c时,这仍然调用getter(由于c的隐形),而getter返回这个> b [c],而不是这个> c的实际值.

以下是您的代码,为了清楚起见,稍作改写:

class Magic
{
    public $a = "publicA";
    protected $values = array( "a" => "valA","b" => "valB","c" => "valC" );
    protected $c = "oldC";

    public function __get( $v )
    {
        echo "[get $v]\n";
        return $this->values[$v];
    }

    public function __set( $var,$val )
    {
        echo "[set $var=$val]\n";
        $this->$var = $val;
    }
}

$m = new Magic();
echo $m->a . "," . $m->c . "\n";
$m->c = "newC";
echo $m->a . "," . $m->c . "\n";

结果:

[get b]      
[get c]
publicA,valB,valC  # no getter for `a` 
[set c=newC]
[get b]
[get c]              # getter still invoked for `c`
publicA,valC  # no getter for `a`

给读者一个练习:

如果您更换点,为什么输出不同.在echo语句中用逗号分隔:

$m = new Magic();
echo $m->a,",$m->b,$m->c,"\n";
$m->c = "newC";
echo $m->a . ","\n";

原文地址:https://www.jb51.cc/php/138165.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐