2010-07-21 6 views
14

Questo è ciò che ho: Tutti gli oggetti che possono essere mantenuti sul database estendono la classe astratta DatabaseObject, che ha tutto il codice logico per controllare effettivamente le modifiche degli attributi ed eseguire le query dei database.Come sovrascrivere una proprietà statica di un oggetto padre e consentire all'oggetto padre di accedere al nuovo valore in PHP?

Sto usando due variabili statiche per definire dettagli specifici dell'oggetto. Li definisco genericamente nella classe base, e quindi presumibilmente li sovrascrivo negli oggetti di database reali.

Il problema è: quando il codice nella classe padre viene effettivamente eseguito, utilizza il valore padre precedente anziché il valore dell'oggetto corrente.

Ecco il codice per la classe di base:

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; 
    } 
} 

Ed ecco il codice per uno degli oggetti che si estendono la classe di base di cui sopra:

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); 
    } 

} 

Che cosa sto facendo male qui? C'è un altro modo per ottenere lo stesso risultato?

Un breve addendum: dichiaro gli attributi nel corpo della classe principalmente per consentire che venga visualizzato dalla funzione di completamento automatico di NetBeans.

+1

possibile duplicato di [ereditarietà di classe in PHP 5.2: sostituzione di variabili statiche nella classe di estensione?] (Http://stackoverflow.com/questions/3017777/class-inheritance-in -php-5-2-overriding-static-variable-in-extension-class) – outis

+0

Questa è una domanda legittima in php, che ha un'implementazione piuttosto confusa, ma la domanda potrebbe davvero essere ristretta per renderla più generica e accessibile per le altre persone di beneficiare. –

risposta

41

Stai cercando Late Static Binding.

quindi è necessario utilizzare:

static::$databaseTable 

invece di

self::$databaseTable 

Questa funzione è disponibile a partire da PHP 5.3. La simulazione di questo in PHP 5.2 è molto difficile, per due motivi: get_called_class è disponibile solo da PHP 5.3. Pertanto, deve essere simulato anche utilizzando debug_backtrace. Il secondo problema è che, se si ha la classe chiamata, non si può ancora usare $calledClass::$property perché questa è una funzione di PHP 5.3. Qui è necessario utilizzare eval o Reflection. Quindi spero che tu abbia PHP 5.3;)

+0

Purtroppo, non posso aggiornare la mia versione di PHP. Il server esegue Plesk 9.5, che supporta solo fino a 5.2.13; Temo che l'aggiornamento manuale potrebbe interrompere alcune applicazioni. Vedrò se riesco a escogitare un modo alternativo per fare lo stesso compito. – DfKimera

+0

Grazie mille per questo suggerimento, ho avuto lo stesso identico problema! –

+0

Il modo migliore prevede il passaggio della classe come primo parametro a qualsiasi metodo che deve accedere a queste proprietà. In questo modo, puoi cercare quella classe direttamente per un override. Se non viene trovato, puoi risalire la scala genitore finché non trovi il campo. –

Problemi correlati