我知道此示例中的static::
和self::
之间存在差异(来自https://stackoverflow.com/a/13613718/2342518)
<?php
class One
{
const TEST = "test1";
function test() { echo static::TEST; }
}
class Two extends One
{
const TEST = "test2";
}
$c = new Two();
$c->test();
使用static::TEST
时返回 test2 ,使用self::TEST
时返回 test1 。
但是当使用$this::TEST
时,它也会返回 test2 。
static::TEST
可以在静态方法中使用,而$this::TEST
在使用之前需要一个实例(因此在静态方法中不可用)。
但是如果在静态方法中不能使用$this::
,static::
可以在非静态方法中使用(如示例中所示)。
那么,静态方法中static ::和this ::之间的区别是什么?
可选的完整测试
<?php
abstract class AOne
{
const TEST = "test1";
abstract public function test();
}
class OneStatic extends AOne
{
public function test()
{
return static::TEST;
}
}
class TwoStatic extends OneStatic
{
const TEST = "test2";
}
class OneSelf extends AOne
{
public function test()
{
return self::TEST;
}
}
class TwoSelf extends OneSelf
{
const TEST = "test2";
}
class OneThis extends AOne
{
public function test()
{
return $this::TEST;
}
}
class TwoThis extends OneThis
{
const TEST = "test2";
}
$objects = array(
'one, static::' => new OneStatic(),
'two, static::' => new TwoStatic(),
'one, self::' => new OneSelf(),
'two, self::' => new TwoSelf(),
'one, $this::' => new OneThis(),
'two, $this::' => new TwoThis(),
);
$results = array();
foreach ($objects as $name=>$object)
$results[$name] = $object->test();
var_dump($results);
?>
哪个收益
因此,self指的是定义方法的类,但在这些非静态方法中$this::
和static::
之间没有区别。
答案 0 :(得分:2)
真的没有一个。 ::
功能随着时间的推移而扩展,因此左侧不需要是类文字,但也可以是具有类名的对象实例或字符串变量。大约在同一时间,使用static
关键字引入了后期静态绑定。正如您所说,$this
不能在静态方法中使用,因此static
是后期静态绑定的明显唯一选择。
在对象实例中,您可以使用static::
来引用后期静态绑定类,它将是当前对象实例的类。或者您可以使用$this::
作为能够使用对象实例作为<class of this object $var>::
的简写的副作用。最终结果是相同的,它只是在这个特定点上恰好重叠的功能。内部运作有所不同,但我想不出有任何差异的情况。
完成维恩图:
只有static
可以执行此操作:
public static function foo() {
static::FOO;
}
只有$var::
可以执行此操作:
$obj = new Foo;
$obj::FOO;
两者都可以做到:
public function foo() {
static::FOO;
$this::FOO;
}
答案 1 :(得分:2)
在三种情况下,您不能使用$this::
而不是static::
1。在静态方法中
public static function test() {
return $this::MY_CONST;
}
输出:
致命错误:未捕获错误:在对象上下文中不使用$ this
2。在非对象上下文中调用的非静态方法中
class A {
const MY_CONST = 33;
public function test() {
return $this::MY_CONST;
}
}
echo A::test(); // test method here is called without instantiating class A
输出:
致命错误:未捕获错误:在对象上下文中不使用$ this
3。使用特殊的::class
关键字
class A {
public function test() {
return $this::class;
}
}
$a = new A;
echo $a->test();
输出:
致命错误:在编译时不允许动态类名
注意:在所有三种情况下,static::
都可以工作
对于最后一种情况 PHP Documentation指出:
注意:
使用:: class的类名称解析是编译时间 转型。这意味着当时的类名字符串是 创建没有自动加载发生。结果,类名 即使该类不存在,也会被扩展。没有发出错误 这种情况。
因此您不能使用$this::class
,因为您不能引用不存在的类