当我在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仅针对不存在或不可见的属性进行调用.换句话说,当你写
原文链接:https://www.f2er.com/php/138165.html$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";