“魔术”“班级”

<?php class gdTemplateDB {
        [...]
     function rewrite_dependencies($section, $id) {
        global $wpdb, $table_prefix;
        /*var_dump($this);
        die;*/
        **include($this->plugin_path.'code/t2/templates.php');**
        [...]
      }
?>

I'm digging through the code of a wordpress plugin called GD star rating.
There are two "magical" things that I cannot figure out why:

  1. The class above apparently has no parents, but when I var_dump the $this pointer, it turns out to be an instance of another class called GDStarRating, and GDStarRating also has no parents! And, you know that the $this pointer cannot be abitrarily reinstantiated. So I can't understand why the $this pointer behaves like that.
  2. The function rewrite_dependencies is statically called from another class (gdTemplateDB::rewrite_dependencies, not $instance->rewrite_dependencies) called gdsrAdmFunc, and that class also doesn't have any parent-child relationships with GdStarRating. But it works just fine.

Please let me know, what can possibly cause those "magic" things?

class a{
  function aa(){
    var_dump($this);
  }
}

class b{
  function bb(){
    a::aa();
  }
}

$ob = new b();
$ob->bb();

here a::aa() outputs

object(b)#1 (0) {   // $this is instance of b
}

Here $this in class a is object of class b because,

function aa of class a is called from function bb class b.

function bb of class b is called from object of class b.

For backwards compatibility reasons, PHP allows you to call non-static methods as static methods. When calling non-static methods in this way, it does not unset $this. Instead, the value from the other instance bleeds through into the new method.

You can duplicate this with the following code:

class A {
  function foo() {
    global $c;
    echo "In A: " . ($this === $c ? 'true' : 'false') . "
";
  }
}

class B {
  function bar() {
    global $c;
    echo "In B: " . ($this === $c ? 'true' : 'false') . "
";
    A::foo();
  }
}

class C {
  function baz() {
    global $c;
    echo "In C: " . ($this === $c ? 'true' : 'false') . "
";
    B::bar();
  }
}

$c = new C();
$c->baz();

Which prints:

In C: true
In B: true
In A: true

However, if you mark static methods as such, then PHP behaves properly and $this is not defined. In this example, if you declare A::foo() as static function foo(), and B::bar() as static function bar(), you see this instead:

In C: true

Notice: Undefined variable: this in test.php on line 13
In B: false

Notice: Undefined variable: this in test.php on line 6
In A: false

is there some extract function call? $this pointer can be abitrarily reinstantiated using this function :P

extract(array('this' => new stdClass));
var_dump($this); // object(stdClass)[1]