drgovyk64676 2014-06-29 12:48
浏览 88
已采纳

静态::和$ this之间的区别::

I know there is a difference between static:: and self:: like in this example ( from 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();

Which returns test2 when static::TEST is used and test1 when self::TEST is used. But it also returns test2 when $this::TEST is used.

static::TEST can be used inside a static method, whereas $this::TEST requires an instance before being used (so non-usable in static methods).

But if one cannot use $this:: in static methods, static:: can be used in non-static methods (like in the example).

So, what is the difference between static:: and $this:: in a non static method?


Optional complete test

<?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);
?>

Which yields

  • 'one, static::' => 'test1'
  • 'two, static::' => 'test2'
  • 'one, self::' => 'test1'
  • 'two, self::' => 'test1'
  • 'one, $this::' => 'test1'
  • 'two, $this::' => 'test2'

So self refers to the class where the method is defined, but there's no difference between $this:: and static:: in these non static methods.

  • 写回答

2条回答 默认 最新

  • 普通网友 2019-08-09 05:05
    关注

    There are three cases when you CAN'T use $this:: over static::

    1. In static methods

    public static function test() {
        return $this::MY_CONST;
    }
    

    Output:

    Fatal error: Uncaught Error: Using $this when not in object context

    2. In none-static methods which get called in none-object context

    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
    

    Output:

    Fatal error: Uncaught Error: Using $this when not in object context

    3. When using the special ::class keyword

    class A {
        public function test() {
            return $this::class;
        }
    }
    
    $a = new A;
    echo $a->test();
    

    Output:

    Fatal error: Dynamic class names are not allowed in compile-time

    Note: in all the three cases static:: will work


    For the last case PHP Documentation states that:

    Note:

    The class name resolution using ::class is a compile time transformation. That means at the time the class name string is created no autoloading has happened yet. As a consequence, class names are expanded even if the class does not exist. No error is issued in that case.

    So you can't use $this::class because you can't reference to non-existent classes

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 神经网络怎么把隐含层变量融合到损失函数中?
  • ¥30 自适应 LMS 算法实现 FIR 最佳维纳滤波器matlab方案
  • ¥15 lingo18勾选global solver求解使用的算法
  • ¥15 全部备份安卓app数据包括密码,可以复制到另一手机上运行
  • ¥15 Python3.5 相关代码写作
  • ¥20 测距传感器数据手册i2c
  • ¥15 RPA正常跑,cmd输入cookies跑不出来
  • ¥15 求帮我调试一下freefem代码
  • ¥15 matlab代码解决,怎么运行
  • ¥15 R语言Rstudio突然无法启动