类构造函数用变量名创建新的类字段


Class constructor creates new class fields with variable names?

我试图通过PHP 5.5.13的构造函数初始化类,但我得到一些奇怪的结果。设置如下:

class foo{
     public $bar;
     public $top;
     public $bot = array();
     function __construct($bar, $top){
        $this->$bar = $bar;
        $this->$top = $top;
     }
}
$phonebook = array();
$user_input = $_POST['query'];
if(/* regex match */){
   foreach($valid_input[0] as $arr){
      $name_and_number = explode(" ", $arr);
      $phonebook[] = new foo($name_and_number[0], (int) $name_and_number[1]); //e.g. Bob, 123
      var_dump($phonebook[count($phonebook)-1]);
   }
}

现在奇怪的是,电话簿的var_dump返回:

object(foo)#1 (5) { ["bar"]=> NULL ["top"]=> NULL ["bot"]=> array(0) { } 
["Bob"]=> string(3) "Bob" ["123"]=> int(123) }
运行:

echo "$phonebook[0]->$bar";
echo "$phonebook[0]['Bob']"; //Since a Bob field apparently exists?
echo "$phonebook[0]->$Bob";  //Just to test if maybe a $Bob variable has been declared?

都返回一个空页。我有点不知所措。我的构造函数设置奇怪吗?或者我访问变量的方式?

你需要做的是去掉第二个$符号,就像这样

class foo{
     public $bar;
     public $top;
     public $bot = array();
     function __construct($bar, $top){
        $this->bar = $bar;
        $this->top = $top;
     }
}

你看到"奇怪"结果的原因是因为$bar$top的值是动态评估的,并将用于创建一个新的命名属性。在您的例子中,结果是一个名为'Bob'和'123'的属性

问题出在以下几行:

 function __construct($bar, $top){
    $this->$bar = $bar;
    $this->$top = $top;
 }

$this->$bar是指以条的值命名的属性。因此,如果您传递名称Bob,实际上您将属性Bob设置为'Bob'

当然,您的意图是设置属性bar。要做到这一点,请删除$标志。对于属性必须省略:

$this->bar = $bar;

所以它与构造函数无关,它只是你在任何地方使用属性的方式。在构造函数中,甚至在类方法之外。echo "$phonebook[0]->$bar"也应该是echo "$phonebook[0]->bar";

我个人认为这是一个奇怪的和反直觉的语法,但是我曾经和一个PHP爱好者在这个问题上有过激烈的争论,所以我不敢再提它。接受现实吧。div;)