You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP OOP继承:子类同名静态变量为何存在两个不同值?

问题原因

PHP中self关键字属于编译时硬绑定,永远指向定义当前方法的类,不会随调用类的变化动态匹配,这是代码里静态属性值不一致的核心原因:

  • dbEntity类中setConnection、getConnection方法里的self::$connection,始终操作的是父类dbEntity自身的静态属性,和子类Patient里重写的同名静态属性完全是两个独立变量。
  • 执行$p->setConnection("myConnection")时,修改的是父类的$connection值,子类Patient自带的$connection = "patientConnection"根本没被改动,所以直接读Patient::$connection和调用方法拿到的结果不一样。
  • 额外注意:父类里$name属性用private修饰,子类无法继承重写这个属性,就算调整绑定关键字也读不到子类定义的$name值。
修复方案

使用PHP提供的延迟静态绑定特性,把方法里所有绑定静态属性的self关键字替换成static即可。static会在运行时动态绑定到实际调用方法的类,能正确识别子类重写的静态属性。
另外如果需要子类重写父类静态属性,要把父类对应属性的访问修饰符从private改成protected(允许子类继承重写)。

修正后的可运行代码:

<?php
Class dbEntity {

    protected static $connection;
    // 访问修饰符从private改为protected,允许子类重写
    protected static $name = "dbEntity";

    public static function getName() {
        // self替换为static
        return static::$name;
    }
    public static function setConnection($connection) {
        // self替换为static
        static::$connection = $connection;
    }
    public static function getConnection() {
        // self替换为static
        return static::$connection;
    }
}

Class Patient extends dbEntity {
    public static $connection = "patientConnection";
    public static $name = "Patient";
}

$p = new Patient();

$p->setConnection("myConnection");

echo $p->getConnection() . "\n"; // 输出:myConnection
echo Patient::$connection . "\n"; // 输出:myConnection
echo $p->getName() . "\n"; // 输出:Patient
补充说明
  • 延迟静态绑定从PHP 5.3.0版本开始正式支持,专门解决继承场景下静态成员的调用绑定问题。
  • 静态属性的存储是按类隔离的,没有绑定关键字做桥接的话,父类和子类的同名静态属性是完全独立的存储空间,不会互相覆盖。

内容的提问来源于stack exchange,提问作者Alpha_B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 06:06:22