之前的文章我们已经讲过,在 php 类的创建过程中,使用 self 作为类本身的引用,使用 $this 作为类对象的引用。
而在 self 和 static 的使用上,有着细微的差别。特别是类继承过程中,self 可能带来意想不到的反应,也正如那篇文章所说,建议使用 static 作为类本身的引用。
本文再来探讨,类内的 new self 与 new static 有什么区别。
self 总是指向 new 关键字所声明的类;static 在静态绑定中,可以指向层级结构中的任意类。
下面举一个例子。
类B继承了类A的方法。对于 get_self 方法,返回的是类A本身。而static则返回的是调用者的类,也就是说,谁调用,static就指向谁。self 则持续地指向声明的类。
上面的代码,我们在类 A 中使用的是 static 静态方法,如果是动态方法,则需要使用到函数 get_class 用于获取类名。下面是一个示例:
方法 create2 中使用了 return new static(),毫无疑问,调用该方法的是对象 $b,那么返回的也肯定是 class B 本身。
方法 create1 中使用 get_class($this) 通过对象本身 $this,获取类名。因为 $this 指向 class B,所以返回的是 B,而 return new $class() 等同于 return new B(),也就是类B本身。
既然我们区分了 self 可以不经类实例化就可以使用其方法,static 必然是实例化后对象的引用,那么看下面这个例子,就会很清楚了:
class Foo {
public $name = static::class;
}
$Foo = new Foo;
echo $Foo->name; // Fatal error
上面的代码会出错。Fatal error 发生位置不是在 $Foo->name 行,而是声明行。因为 static::class 会发生错误。在对属性赋值时,只能使用非静态绑定的对象,同理 $this 的方法可肯定不行。要使用 self。
class Foo {
public $name = self::class;
}
$Foo = new Foo;
echo $Foo->name; // Foo
这样写就没错了。因为 self 引用的是类本身,调用 class 静态方法也完全行得通。
在程序架构时这些基类的设计很关键,需要详细规划和细分业务关系,self static $this 这些高频关键字,需要我们熟练掌握。
HAppy coding :_)