Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Class constructor creates new class fields with variable names? [closed]

I'm trying to initialize a class through a constructor with PHP 5.5.13 but am getting some weird results. The setup is like this:

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]);
   }
}

The weird part is now, however that phonebook's var_dump returns:

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

Running:

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?

All return an empty page. I'm at a loss here. Is my constructor setup weird? Or the way I try to access the variables?

like image 953
Jan Bartels Avatar asked Aug 09 '26 15:08

Jan Bartels


2 Answers

What you need to do is get rid of the second $ sign like so

class foo{
     public $bar;
     public $top;
     public $bot = array();

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

The reason why you're seeing the 'weird' results is because the value of $bar and $top are evaluated dynamically and will be used to create a new named property. Resulting, in your case, to a property named 'Bob' and '123'

like image 179
Jeroen Smit Avatar answered Aug 11 '26 05:08

Jeroen Smit


The problem is in these lines:

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

$this->$bar refers to the property that is named after the value of bar. So if you pass the name Bob, you actually set the property Bob to 'Bob'.

Your intention, of course, is to set the property bar. To do that, remove the $ sign. It must be omitted for properties:

$this->bar = $bar;

So it has nothing to do with the constructor, it's just the way you use properties anywhere. In a constructor or even out of class methods. echo "$phonebook[0]->$bar" should also be echo "$phonebook[0]->bar";.

Personally I think this is a weird and counter intuitive syntax, but I've once been in a serious fight over it with a PHP afficionado, so I don't dare to bring it up again. Just live with it. ;)

like image 37
GolezTrol Avatar answered Aug 11 '26 05:08

GolezTrol



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!