如何覆盖父对象的静态属性并让父对象访问 PHP 中的新值?

Posted

技术标签:

【中文标题】如何覆盖父对象的静态属性并让父对象访问 PHP 中的新值?【英文标题】:How to override a static property of a parent object and let the parent object access the new value in PHP? 【发布时间】:2011-03-19 05:33:44 【问题描述】:

这就是我所拥有的:可以在数据库中持久化的所有对象都扩展了 DatabaseObject 抽象类,该抽象类具有实际监视属性更改和运行数据库查询的所有逻辑代码。

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

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

这是基类的代码:

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 的自动完成功能看到它。

【问题讨论】:

Class inheritance in php 5.2: Overriding static variable in extension class?的可能重复 这是 php 中的一个合法问题,它的实现相当混乱,但该问题确实可以缩小范围,使其更通用且易于其他人从中受益。 【参考方案1】:

您正在寻找Late Static Binding。

所以你需要使用:

static::$databaseTable

而不是

self::$databaseTable

此功能自 PHP 5.3 起可用。在 PHP 5.2 中进行模拟非常困难,原因有二:get_called_class 也仅在 PHP 5.3 之后才可用。因此也必须使用debug_backtrace 对其进行模拟。第二个问题是,如果你有被调用的类,你仍然不能使用$calledClass::$property,因为这也是 PHP 5.3 的一个特性。这里需要使用evalReflection。所以我希望你有 PHP 5.3 ;)

【讨论】:

很遗憾,我无法升级我的 PHP 版本。服务器运行的是 Plesk 9.5,最高只支持 5.2.13;我担心手动升级它可能会破坏某些应用程序。我会看看我是否可以设计一种替代方法来完成同样的任务。 非常感谢您的提示,我遇到了完全相同的问题! 最好的方法是将类作为第一个参数传递给任何需要访问这些属性的方法。这样,您可以直接在该类中搜索覆盖。如果没有找到,您可以爬上父阶梯,直到找到该字段。

以上是关于如何覆盖父对象的静态属性并让父对象访问 PHP 中的新值?的主要内容,如果未能解决你的问题,请参考以下文章

java中私有的属性、静态成员可以被子类继承吗?

php父类中访问子类的静态属性

PHP面向对象编程简单实例

PHP面向对象编程

绑定与非绑定方法 继承 继承与抽象 查找属性关系 派生与覆盖 访问父类的内容

PHP 从静态方法访问对象的受保护属性