php面向对象重载
我遇到了以下代码,无法理解为什么使用php的get和set magic方法以非直观的顺序输出脚本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";
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不能用于连接,因为它应该是无效的。