在PHP中,常量的继承行为在PHP 7前后确实发生了变化,尤其是在使用self::
和static::
时。这种变化主要与PHP 7引入的“后期静态绑定”(Late Static Binding)有关。
在PHP 5.x中,self::
关键字总是引用定义它的类,而不是运行时调用的类。这意味着,如果你在一个父类中定义了一个常量,并在子类中重写了这个常量,使用self::
引用该常量时,PHP 5.x会始终引用父类中的常量,而不是子类中的常量。
class A {
const X = 'A';
public static function getX() {
return self::X;
}
}
class B extends A {
const X = 'B';
}
echo B::getX(); // 输出 'A'
在上面的例子中,B::getX()
调用的是A::getX()
,而self::X
在A
类中定义,因此输出的是A
。
在PHP 7中,self::
的行为发生了变化。self::
现在会引用调用它的类,而不是定义它的类。这意味着如果你在子类中重写了常量,self::
会引用子类中的常量。
class A {
const X = 'A';
public static function getX() {
return self::X;
}
}
class B extends A {
const X = 'B';
}
echo B::getX(); // 输出 'B'
在这个例子中,B::getX()
调用的是A::getX()
,但self::X
现在引用的是B
类中的常量,因此输出的是B
。
static::
的行为如果你希望在PHP 5.x和PHP 7中都能引用子类中的常量,可以使用static::
关键字。static::
实现了“后期静态绑定”,它会根据调用时的类来决定引用哪个常量。
class A {
const X = 'A';
public static function getX() {
return static::X;
}
}
class B extends A {
const X = 'B';
}
echo B::getX(); // 输出 'B' (在PHP 5.x和PHP 7中都是如此)
在这个例子中,static::X
会根据调用时的类来决定引用哪个常量。因此,无论是在PHP 5.x还是PHP 7中,B::getX()
都会输出B
。
self::
总是引用定义它的类中的常量。self::
会引用调用它的类中的常量。static::
。这种变化是为了使PHP的行为更加一致和可预测,尤其是在涉及继承和重写时。