我只是问了这个关于self::
关键字的问题,没有意识到static::
关键字的存在。
在我看来,如果需要显式引用某个特定类,则可以使用ClassName::
,否则您会希望self::
表示调用该方法的类。我想举一个例子,说明您何时需要self::
,而不能只使用ClassName::
。
是否可以用ClassName::
替换所有出现的self::
,其中ClassName是它所在的类外壳的名称并不是说它在语义上更好,甚至是等价的,而是从功能上讲。。。
self
转发静态调用,而ClassName
不转发,换句话说:它解析为当前类实例。
在某些情况下,您可能希望引用当前实例,而不是类的扩展实例。
这只对PHP 5.3及更高版本中的后期静态绑定以及引入static
关键字的原因非常重要。
我可能会将self::
描述为忽略被覆盖或多态的类,因为它将始终使用父类,即使它已经被覆盖。
class A{
public function foo(){
echo "hello Mike";
}
}
class B extends A{
public function foo(){
echo "this will be ignore";
}
}
$tryThis = new B();
$tryThis->foo();
// Above will print out
// Hello Mike
简短回答:是
我很好奇这是否会受到命名空间更改、继承或函数受保护状态的影响,但事实并非如此。我想不出还有什么能影响它。
我认为self
比ClassName
更好,因为如果您更改封闭类上的类名或将代码粘贴到新类中,它会继续工作。
证明:
namespace Foo;
Class B{
protected static function printOut()
{
echo "Defined in Foo'B name: ".__CLASS__."'n";
}
}
Class A extends B{
public static function testClassName(){
A::printOut();
}
public static function testSelf(){
self::printOut();
}
public static function testStatic(){
static::printOut();
}
}
namespace Bar;
use Foo'A as B;
Class A extends B{
protected static function printOut(){
echo "Defined in Bar'A name: ".__CLASS__."'n";
}
}
$a = new A();
$b = new B();
$a->testClassname(); //Defined in Foo'B name: Foo'B
$a->testSelf(); //Defined in Foo'B name: Foo'B
$a->testStatic(); //Defined in Bar'A name: Bar'A
$b->testClassname(); //Defined in Foo'B name: Foo'B
$b->testSelf(); //Defined in Foo'B name: Foo'B
$b->testStatic(); //Defined in Foo'B name: Foo'B
如您所见,调用Bar''A->printOut()的唯一时间是在Foo''A中使用static
时