(PHP)为什么这是以下回显的输出?

时间:2018-12-03 22:03:57

标签: php function class

我正在为考试准备一些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,我一生无法理解为什么这是正确的答案。

3 个答案:

答案 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

我想关键是要演示两件事:

  1. 仅针对不可直接访问(即不公开)的属性调用PHP的magic __get方法。然后,该方法的实现可以返回任何字符串-在这种情况下,属性名称用于查找其他数组的元素。

  2. 在使用字符串之前,已解析连接成字符串的变量。因此,__get方法被调用了两次(用于不可访问的属性bc),并且在字符串本身被调用之前,回声语句 inside 被调用了并显示。

使用c方法可以类似地解决在两个“ echo”行之间设置属性__set的调用,尽管这对其余代码没有任何影响。

演示:https://3v4l.org/4Bitg

答案 2 :(得分:-1)

表面上的答案是错误的(或者您在记下错字):

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

访问C,c时,序列c,C是不可能的,必须为$m->c