如何重写父对象的静态属性并让父对象在PHP中访问新值?

如何重写父对象的静态属性并让父对象在PHP中访问新值?,php,oop,static,properties,overriding,Php,Oop,Static,Properties,Overriding,这就是我所拥有的:所有可以在数据库上持久化的对象都扩展了DatabaseObject抽象类,它拥有所有的逻辑代码来实际监视属性更改并运行DatabaseQuery 我使用两个静态变量来定义特定于对象的细节。我一般在基类中定义它们,然后假设我在实际的数据库对象中覆盖它们 问题是:当父类中的代码实际执行时,它使用旧的父值而不是当前的对象值 下面是基类的代码: abstract class DatabaseObject { public $id; private static $d

这就是我所拥有的:所有可以在数据库上持久化的对象都扩展了DatabaseObject抽象类,它拥有所有的逻辑代码来实际监视属性更改并运行DatabaseQuery

我使用两个静态变量来定义特定于对象的细节。我一般在基类中定义它们,然后假设我在实际的数据库对象中覆盖它们

问题是:当父类中的代码实际执行时,它使用旧的父值而不是当前的对象值

下面是基类的代码:

abstract class DatabaseObject {

    public $id;

    private static $databaseTable = NULL;
    private static $databaseFields = array();

    private $data = array();
    private $changedFields = array();

    public function IDatabaseObject($id) {
    $this->id = $id;
    $this->data = Database::GetSingle(self::$databaseTable, $id);

    Utils::copyToObject($this, $this->data, self::$databaseFields);
    }

    public static function Load($id) {
    return new self($userID);
    }

    public static function Create($data) {

    $id = Database::Insert(self::$databaseTable, $data);

    return new self($id);
    }

    public function Save() {
    $data = Utils::copyFromObject($this, $this->changedFields);

    Database::Update(self::$databaseTable, $data, $this->id);

    }

    public function __constructor() {
    // We do this to allow __get and __set to be called on public vars
    foreach(self::$databaseFields as $field) {
        unset($this->$field);
    }
    }

    public function __get($variableName) {
    return $this->$variableName;
    }

    public function __set($variableName, $variableValue) {
    // We only want to update what has been changed
    if(!in_array($variableName, $this->changedFields) && in_array($variableName, self::$databaseFields)) {
        array_push($this->changedFields, $variableName);
    }

    $this->$variableName = $variableValue;
    }
}
下面是扩展上述基类的其中一个对象的代码:

class Client extends DatabaseObject {

    public static $databaseTable = "clients";
    public static $databaseFields = array("name","contactName","primaryUserID","email","is_active","rg","cpf","cnpj","ie","addrType","addrName","addrNumber","addrComplement","addrPostalCode","addrNeighborhood","addrCity","addrState","addrCountry","phoneLandline","phoneFax","phoneMobile");

    public $name;
    public $contactName;

    public $primaryUserID;
    public $email;

    public $is_active;

    public $rg;
    public $cpf;
    public $cnpj;
    public $ie;

    public $addrType;
    public $addrName;
    public $addrNumber;
    public $addrComplement;
    public $addrPostalCode;
    public $addrNeighborhood;
    public $addrCity;
    public $addrState;
    public $addrCountry;

    public $phoneLandline;
    public $phoneFax;
    public $phoneMobile;

    public static function Load($id) {
 return new Client($id);
    }

}
我做错了什么?有没有其他方法可以达到同样的效果

一个简短的补充:我在类主体中声明属性主要是为了让NetBeans的自动完成功能能够看到它。

您正在寻找的

因此,您需要使用:

static::$databaseTable
而不是

self::$databaseTable

此功能从PHP5.3开始提供。在PHP5.2中模拟这一点非常困难,原因有两个:
get\u called\u class
也只有在PHP5.3之后才可用。因此,也必须使用
debug\u backtrace
对其进行模拟。第二个问题是,如果您有被调用的类,您仍然可能不会使用
$calledClass::$property
,因为这也是PHP5.3的特性。这里您需要使用
eval
Reflection
。因此,我确实希望您有PHP5.3;)

不幸的是,我无法升级我的PHP版本。服务器运行Plesk 9.5,最多支持5.2.13;我担心手动升级可能会破坏某些应用程序。我会看看我是否能想出一个替代的方法来完成同样的任务。非常感谢你给我这个提示,我也有同样的问题!最好的方法是将类作为第一个参数传递给需要访问这些属性的任何方法。这样,您就可以直接在该类中搜索重写。如果找不到,您可以向上搜索父级,直到找到该字段。在php中,这可能是一个合法的问题,它有一个相当混乱的实现,但这个问题实际上可以缩小范围,使其更通用,并可供其他人使用。