Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php面向对象重载_Php_Overloading_Magic Methods - Fatal编程技术网

php面向对象重载

php面向对象重载,php,overloading,magic-methods,Php,Overloading,Magic Methods,我遇到了以下代码,无法理解为什么使用php的get和set magic方法以非直观的顺序输出脚本 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";

我遇到了以下代码,无法理解为什么使用php的get和set magic方法以非直观的顺序输出脚本

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?输出顺序没有意义。

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

原因是魔法方法只有在被触发时才会被触发

因此,对于第一个echo,它获取
$m->a
这是一个可访问的属性,因此它不是从
\uu 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)

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

如果你把它们分开呼出,一切都会顺其自然

echo $m->a . "," . $m->b . "," . $m->c . ",";
调用此行时,它首先解析变量名,然后再进行连接

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

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


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

请给变量和值起一个有意义的名字,读起来很痛苦。所以你可以说它在输出整个计算之前执行了某种“预处理”。@robertrocha。当字符串被连接时,将采用连接运算符左侧的字符串,并将其连接到右侧的字符串。如果两个字符串都未知,解释器将无法连接它们,除非找到需要与另一个字符串合并的字符串。我想我现在了解了它的工作原理。对代码行进行求值。由于get、set方法在整行被回显之前执行回显,显示顺序被打乱,因为这两个方法绕过了父回显和单独回显。@robertrocha是的,注意setter不能用于连接,因为它应该是无效的。