我正在为考试准备一些PHP问题,在下面的问题中,显然(B)是答案。
以下代码的输出是什么?
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;
- A:A,数组,数组,A,数组,数组,CC
- B:b,c,A,B,C,c:CC,b,c,A,B,C
- C:a,b,c,A,B,C,c:CC,a,b,c,A,B,C
- D:b,c,A,B,C,c:CC,b,c,A,B,CC
很抱歉出现noob问题,但是来自Java,我一生无法理解为什么这是正确的答案。
答案 0 :(得分:3)
$b
和$c
是受保护的属性,因此不能从类范围之外进行设置。 $a
是公开的,因此可以直接设置/访问。
要访问$b
和$c
,它将退回到魔术吸气剂,该吸气剂从$b
数组中检索值。
逻辑如下:
b, <- getter echo (executed by $m->b)
c, <- getter echo (executed by $m->c)
A, <- public property value (this is the start of the first global echo expression)
B, <- getter return b[b]
C, <- getter return b[c]
c: CC, <- setter echo, sets c = CC, but c is never accessed
b, <- getter echo (executed by $m->b)
c, <- getter echo (executed by $m->c)
A, <- public property value (this is the start of the second global echo expression)
B, <- getter return b[b]
C <- getter return b[c]
首先处理吸气剂回声,因为它们的回声语句在回声表达式(带有连接)完成求值之前就已到达。
由于$a
是公开的,因此不会使用魔术师或吸气剂。
答案 1 :(得分:3)
此简化版本是否更清晰?
class Magic
{
public $a = "A";
protected $b = ['a' => 'A', 'b' => 'B', 'c' => 'C'];
public function __get($v)
{
echo "A MAGIC METHOD IS BEING CALLED TO GET THE PROPERTY $v", PHP_EOL;
return $this->b[$v];
}
}
$m = new Magic;
echo ($m->a . ',' . $m->b . ',' . $m->c);
正在调用一种神奇的方法来获取属性b
正在调用一种神奇的方法来获取属性c
A,B,C
我想关键是要演示两件事:
仅针对不可直接访问(即不公开)的属性调用PHP的magic __get
方法。然后,该方法的实现可以返回任何字符串-在这种情况下,属性名称用于查找其他数组的元素。
在使用字符串之前,已解析连接成字符串的变量。因此,__get
方法被调用了两次(用于不可访问的属性b
和c
),并且在字符串本身被调用之前,回声语句 inside 被调用了并显示。
使用c
方法可以类似地解决在两个“ echo”行之间设置属性__set
的调用,尽管这对其余代码没有任何影响。
答案 2 :(得分:-1)
表面上的答案是错误的(或者您在记下错字):
B: b,c,A,B,C,c: CC,b,c,A,B,C
访问C,c
时,序列c,C
是不可能的,必须为$m->c
。