Craig Taub
Craig Taub

Reputation: 4179

Why is this Getter and Setter behaving like this?

I recently came across this code question and am very unclear as to why it is producing these results.

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]; //internal so fine with protected.
   }

   public function __set($var, $val ) {
      echo "$var: $val,";
      $this->$var = $val;
   }
}

$m = new Magic();

//1
//echo $m->a;
//prints A

//2
//echo $m->a;
//echo $m->b;
//prints Ab, B

//3
//echo $m->a.",," . $m->b; 
//prints b,A,,B

I can not understand the behaviour for number 3. If somebody could explain I would be very appreciative as I can't find any answers anywhere on this behaviour.

I understand access modifiers and property visibility but I must have some gaps as not sure why 'b' is printing first as the getter calling the protected property is allowed to do so.

Additionally I would have thought 'A' would have printed first (like 1 and 2).
Find it strange why it behaves differently when it echoes both 'a' and 'b' at same time.

The only thing I can think is with echo
-With the comma version, each argument is evaluated and echoed in turn
-The dot version is different, it has to be fully evaluated before it can be echoed as requested.
But not sure (how does it evaluate?).

Thanks

Upvotes: 1

Views: 126

Answers (2)

Timothée Groleau
Timothée Groleau

Reputation: 1950

That has nothing to do with PHP OOP per say but with the order of evaluation of operands:

echo ($m->a . ",," . $m->b);

is a concatenation of 3 operands:

  • $m->a : by itself returns "A"
  • ,,: returns ",," (duh)
  • $m->b does TWO things by calling $m->__get('b'): FIRST it echos "b," (in the getter function itself), THEN returns "B" for concatenation.

So by the time the 3 operands have been concatenated into one string "A,,B", the program has already echo-ed "b,". Then the concatenated string is passed to YOUR command echo for output, hence final result: "b,A,,B"

Upvotes: 1

bitWorking
bitWorking

Reputation: 12655

It's because of the echo in __get method. If you call echo $m->a.",," . $m->b; than first the functions inside statement get called. So the echo in __get will be first called.

Upvotes: 2

Related Questions