PHP 中的 self::$bar 和 static::$bar 有什么区别?

2022-08-30 06:32:17

在下面的示例中使用 和 之间有什么区别?selfstatic

class Foo
{
    protected static $bar = 1234;

    public static function instance()
    {
        echo self::$bar;
        echo "\n";
        echo static::$bar;
    }

}

Foo::instance();

生产

1234
1234

答案 1

当您用于引用类成员时,您指的是在其中使用关键字的类。在本例中,您的类定义了一个名为 的受保护静态属性。在类中使用以引用属性时,引用的是同一类。selfFoo$barselfFoo

因此,如果您尝试在类中的其他位置使用,但您的类具有不同的属性值,它将使用 代替 ,这可能不是您的预期:self::$barFooBarFoo::$barBar::$bar

class Foo
{
    protected static $bar = 1234;
}

class Bar extends Foo
{
    protected static $bar = 4321;
}

当您通过 调用方法时,您正在调用一个称为后期静态绑定的功能(在 PHP 5.3 中引入)。static

在上面的场景中,使用将导致 (1234)。使用将导致 (4321),因为 使用 ,解释器会考虑运行时类中的重新声明。selfFoo::$barstaticBar::$barstaticBar

// self
var_dump(Foo::$bar);
// (int) 1234

// static
var_dump(Bar::$bar);
// (int) 4321

您通常对方法甚至类本身使用后期静态绑定,而不是属性,因为您通常不会在子类中重新声明属性。使用关键字调用后期绑定构造函数的示例可以在以下相关问题中找到:新 self 与新静态static

但是,这并不排除与属性一起使用。static


答案 2

我有一个小例子,显示了 和 之间的区别。Using 执行后期静态绑定,因此它从子类绑定变量值。selfstaticstatic::

class A { // Base Class
    protected static $name = 'ClassA';
    public static function getSelfName() {
        return self::$name;
    }
    public static function getStaticName() {
        return static::$name;
    }
}

class B extends A {
    protected static $name = 'ClassB';
}

echo A::getSelfName(); // ClassA
echo A::getStaticName(); // ClassA

echo B::getSelfName(); // ClassA
echo B::getStaticName(); // ClassB

推荐