1、this

当一个对象要访问其方法时,会先完成一个绑定:将 ​​$this​​​ 绑定到调用该方法的 ​​对象​​​。方法谁调用,​​$this​​ 就指向谁。

2、self

self 永远指向 ​​定义它的类​​。也就是你在哪里写了 self,self 就代表哪个类。

​$this​​ 绑定的是调用方法的对象,是对象级别,self 则是绑定的定义它的类,是类级别。因此只能用于访问静态方法或静态属性或常量。

3、parent

跟 self 类似,parent 指向的是定义它的 ​​类的父类​​。也是类级别。

class AA
{
public $name = 'AA <br/>';

public static $age = 'AA 12 <br/>';
}

class BB extends AA
{
public $name = 'BB <br/>';

public static $age = 'BB 12 <br/>';

public function foo()
{
echo self::$age;//BB 12

echo parent::$age;//AA 12

echo parent::$name;//Fatal error: Access to undeclared static property: AA::$name

//echo parent->$name;//Parse error
}

}

$bb = new BB();
$bb->foo();

4、static

static 关键字是 PHP 5.3 时引入的,官方名称是延迟静态绑定(late-static-bindings)。static 关键字可以在父类中引用到扩展类的最终状态,也就是指向 ​​调用它的类​​。换句话,当碰到 static 关键字时,static 就指向了当前的调用域(calling scope),而不是像 self 等静态引用会寻找定义他们的域。

class AA
{
public static $age = 'AA 12 <br/>';

public function foo()
{
echo self::$age;//AA 12
echo static::$age;//BB 12
static::bar();//BB bar(
static::bar1();//BB bar1()

}
}

class BB extends AA
{
public static $age = 'BB 12 <br/>';

public static function bar()
{
echo 'BB bar() <br/>';
}

public function bar1()
{
echo 'BB bar1() <br/>';
}
}

$bb = new BB();
$bb->foo();

可以看到,static 关键字绑定了调用方法的类,而不是定义方法的类。一来来说,static 用于调用调用类的静态方法但不限于静态方法,例子中 BB 中的bar1() 就是非静态的,一样可以正常运行,不像 self、parent 一样会出错,但毕竟是类级别的绑定,还是必须使用 :: 而不能使用 ->。

手册上有这么一句话:后期静态绑定的解析会一直到取得一个完全解析了的静态调用为止。另一方面,​​如果静态调用使用 parent:: 或者 self:: 将转发调用信息​​。附加的例子也被面试者经常拿来考人。

class A {
public static function foo() {
static::who();
}

public static function who() {
echo __CLASS__."\n";
}
}

class B extends A {
public static function test() {
A::foo();//A调用A自己的foo(),static指向调用者当然为A

parent::foo();//parent指的是当前类的父类A,调用者依然是C,
//parent只是起到了“转发调用者”的作用。
//A中的foo内的static解析到C,最后运行的是C的who(),输出的是__CLASS__为C

self::foo();//同样的转发调用者,是C要调用B中的foo(),
//千万不要理解为是B要调用B自己的foo()。这样理解的话结果就是B了。
}

public static function who() {
echo __CLASS__."\n";
}
}

class C extends B {
public static function who() {
echo __CLASS__."\n";
}
}

C::test();//test()来自B。结果为A C C

手册上在非静态环境下使用static的例子引还引起了我的注意,不是不理解 static,而是对 ​​$this​​ 的行为让人诧异。

class A
{
private function foo()
{
echo 'A foo()<br/>';
}

public function test()
{
$this->foo();//如果当前类中有foo且为private,会被运行。否则运行子类的
}
}

class C extends A
{
public function foo()
{
echo 'C foo()<br/>';
}
}

$c = new C();
$c->test();//A中的foo()为private,运行A的。否则运行C的

$this-> will try to call private methods from the same scope