1

我遇到了以下代码,无法弄清楚为什么使用 php 的 get 和 set 魔术方法以非直观的顺序输出脚本的输出。

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;

输出是:

bcA,B,C,c
CCbcA,B,C

首先,为什么它不输出 A 作为第一件事?输出顺序没有意义。

4

3 回答 3

1

有人正在学习 Zend 认证;-)

原因是只有在属性不可访问时才会触发魔术方法。

因此,对于第一个回显,它获取$m->athis 是一个可访问的属性,因此它不会被回显,而是__get被简单地返回。在此之后,两者$b$c都无法访问,因此它们被回显然后返回。

所以第一个回声的输出是:

b // echo'd by __get
c // echo'd by __get
A // simply returned, and echo'd in the concatenated string
B // (As above)
C // (As above)
于 2013-02-19T13:37:00.840 回答
1

原因很简单。您进行字符串连接,因此 PHP 必须在输出一个之前准备完整的字符串。这意味着它执行需要连接的所有内容。当它执行时getter__get仅对不可访问的成员调用方法)echo,首先执行然后返回值。

如果你分别回应它们,一切都会在它的位置上。

于 2013-02-19T13:37:26.393 回答
0
echo $m->a . "," . $m->b . "," . $m->c . ",";

当调用此行时,它首先在连接发生之前解析变量名称。

所以它查找 $m->a,然后是 $m->b,然后是 $m->c。

由于 $m->a 解析为您的公共属性 a,因此它不会触发您的_get,因此不会立即发送其中的回声。但是,$m->b确实会触发它,这会导致它得到回显。

最后,一旦变量被解析,整个连接的字符串就会得到输出。

于 2013-02-19T13:38:29.003 回答