插件窝 干货文章 PHP常量继承中self::X的含义:为什么PHP 7前后输出结果不同?

PHP常量继承中self::X的含义:为什么PHP 7前后输出结果不同?

常量 PHP self 输出 969    来源:    2025-03-15

在PHP中,self::X 用于引用当前类中定义的常量 X。在PHP 7之前和之后,self::X 的行为在某些情况下可能会有所不同,尤其是在涉及到继承和常量重写时。

PHP 5.x 和 PHP 7.x 的区别

在PHP 5.x中,self::X 的行为是静态绑定的,这意味着它总是引用定义它的类中的常量,而不是运行时实际调用的类中的常量。这可能会导致一些意外的行为,尤其是在继承链中。

在PHP 7.x中,PHP引入了更严格的常量继承规则,self::X 的行为变得更加一致和可预测。self::X 现在会引用定义它的类中的常量,而不是运行时实际调用的类中的常量。

示例代码

class A {
    const X = 'A';
    public static function getX() {
        return self::X;
    }
}

class B extends A {
    const X = 'B';
}

echo B::getX(); // 输出结果在PHP 5.x和PHP 7.x中不同

PHP 5.x 的输出

在PHP 5.x中,self::X 会引用定义它的类 A 中的常量 X,因此输出结果为:

A

PHP 7.x 的输出

在PHP 7.x中,self::X 仍然引用定义它的类 A 中的常量 X,因此输出结果也是:

A

为什么会有不同的输出?

在PHP 5.x中,self::X 的行为可能会导致一些混淆,尤其是在继承链中。PHP 7.x通过引入更严格的常量继承规则,使得 self::X 的行为更加一致和可预测。

如何解决?

如果你希望在子类中重写常量,并且希望在调用时使用子类的常量,可以使用 static::X 而不是 self::Xstatic::X 是后期静态绑定(Late Static Binding),它会根据实际调用的类来决定使用哪个常量。

class A {
    const X = 'A';
    public static function getX() {
        return static::X;
    }
}

class B extends A {
    const X = 'B';
}

echo B::getX(); // 输出 'B'

在这个例子中,static::X 会根据实际调用的类 B 来决定使用哪个常量,因此输出结果为 B

总结

  • 在PHP 5.x中,self::X 总是引用定义它的类中的常量。
  • 在PHP 7.x中,self::X 的行为更加一致,仍然引用定义它的类中的常量。
  • 如果你希望在子类中重写常量,并且希望在调用时使用子类的常量,可以使用 static::X 而不是 self::X