【问题标题】:Difference between static:: and $this::static:: 和 $this:: 之间的区别
【发布时间】:2014-06-29 12:48:09
【问题描述】:

我知道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);
?>

产量

  • 'one, static::' => 'test1'
  • '二,静态::' => 'test2'
  • 'one, self::' => 'test1'
  • '二,self::' => 'test1'
  • '一,$this::' => 'test1'
  • '二,$this::' => 'test2'

所以 self 指的是定义方法的类,但是在这些非静态方法中$this::static:: 没有区别。

【问题讨论】:

标签: php static this self


【解决方案1】:

在三种情况下不能使用$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 的类名解析是一个编译时间 转型。这意味着当时的类名字符串是 created 还没有发生自动加载。因此,类名 即使类不存在也会被扩展。没有错误发出 那个案例。

所以你不能使用$this::class,因为你不能引用不存在的类

PHP 8

PHP 8 中的行为发生了变化!

出于一致性原因,$this::class 现在提供与get_class($this)static::class 相同的结果

https://3v4l.org/iB99O

【讨论】:

  • 我确实忘记了 $this::class 这是一个很好的例子,因为其他人实际上是基于静态方法(或“称为静态”,即任何地方 $this 不存在)
【解决方案2】:

真的没有。 :: 功能随着时间的推移而扩展,因此左侧不需要是类字面量,也可以是具有类名的对象实例或字符串变量。大约在同一时间,static 关键字引入了后期静态绑定。正如您所说,$this 不能用于静态方法中,因此 static 是这里用于后期静态绑定的明显且唯一的选择。

但是,在对象实例中,您可以使用static:: 来引用后期静态绑定类,这将是当前对象实例的类。或者您可以使用$this:: 作为能够使用对象实例作为&lt;class of this object $var&gt;:: 的简写的副作用。最终结果是一样的,只是功能恰好在这个特定点重叠。内部运作有些不同,但我想不出有什么不同的情况。

只是为了完成维恩图:

只有static 可以这样做:

public static function foo() {
    static::FOO;
}

只有$var:: 可以这样做:

$obj = new Foo;
$obj::FOO;

两者都可以:

public function foo() {
    static::FOO;
    $this::FOO;
}

【讨论】:

    猜你喜欢
    • 2013-10-23
    • 2018-11-02
    • 2016-06-17
    • 2012-08-18
    • 2017-12-22
    • 2012-03-15
    • 1970-01-01
    • 2016-01-07
    • 1970-01-01
    相关资源
    最近更新 更多