Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of return and echo in php

Tags:

php

I am confused about how the program is working; the code should print A, bB but it is showing bA,B

class SampleClass {
    public $a = "A";
    protected $b = array ("a" => "A", "b" => "B", "c" => "C");

    public function __get($v){
        echo "$v";
        return $this->b[$v];
    }
}

$m = new SampleClass();

echo $m->a . ", " . $m->b;
like image 771
Dudling Avatar asked Sep 17 '15 14:09

Dudling


2 Answers

This makes perfect sense really. Let's think about the execution order:

Before PHP can ECHO your requested string, it must evaluate it first (i.e. the $m->a . ", " . $m->b part)

So at this point, the parser tries to resolve $m->a and $m->b, it resolves the first, but the 2nd fails, so we go to the magic method.

The magic method echos something (the first `b), and then resolves itself to B.

Now, we need to finish what we started (the original echo).

So what do we have?

  1. resolve the $m->b(echo in b in the process).
  2. echo "A,B"

combine it all together?

bA,B

like image 64
Patrick Avatar answered Sep 18 '22 13:09

Patrick


This is odd isn't it but it isn't doing what you think it is doing.

Running this code does something different.

class SampleClass {
    public $aaa = "A";
    protected $b = array ("a"=> "A", "b" => "B", "c" => "C");

    public function __get($v){
        echo "$v";
        return $this->b[$v];
    }
}


$m = new SampleClass();

echo "[" . $m->a. ", ". $m->b. ", ". $m->c . "]";

Output is:

abc[A, B, C]

Your original __get does not get called when you do $m->a since there is a variable 'a' anyhow. It is only called as a last resort so you should write your own specific 'getter' function instead.

like image 40
Dean Jenkins Avatar answered Sep 21 '22 13:09

Dean Jenkins