gpt4 book ai didi

php - 魔法 setter/getter / setter/getter 未被调用

转载 作者:可可西里 更新时间:2023-10-31 23:06:08 25 4
gpt4 key购买 nike

在阅读Zend PHP Certification学习指南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 . ", " . $m->b . ", " . $m->c . ", ";

这段代码的输出是:

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

为什么这段代码不打印a,它是如何工作的?

最佳答案

__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 不调用 getter。现在,由于您还定义了 setter,magic->c = CC 实际上更改了类的 protected 成员,因此,当您回显 magic-> c 之后,this 仍然调用 getter(由于 c 的不可见性),并且 getter 返回 this->b[c],而不是this->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->b . ", " . $m->c . "\n";
$m->c = "newC";
echo $m->a . ", " . $m->b . ", " . $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, valB, valC # no getter for `a`

给读者的练习:

如果将 echo 语句中的点 . 替换为逗号,为什么输出会不同:

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

关于php - 魔法 setter/getter / setter/getter 未被调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27077548/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com