PHP this parent static self 关键字
原创
©著作权归作者所有:来自51CTO博客作者郎涯工作室的原创作品,请联系作者获取转载授权,否则将追究法律责任
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