2010-07-21 13 views
14

Sahip olduğum şey: Veritabanında kalıcı olabilecek tüm nesneler, öznitelik değişikliklerini gerçekte izlemek ve veritabanı sorgularını çalıştırmak için tüm mantık koduna sahip olan DatabaseObject özet sınıfını genişletir.Bir üst nesnenin statik özelliğini nasıl geçersiz kılar ve üst nesnenin PHP'deki yeni değere erişmesine izin verilir?

Nesne özgü ayrıntıları tanımlamak için iki statik değişken kullanıyorum. Onları temel sınıfta genel olarak tanımlarım ve daha sonra onları gerçek veritabanı nesnelerine yazdım.

Sorun şu: Ana sınıftaki kod gerçekten çalıştırıldığında, geçerli nesne değeri yerine eski üst değer kullanılır.

İşte temel sınıf için kod:

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

Ve burada yukarıdaki temel sınıf uzanan nesnelerin biri için kod: Yanlış Burada ne işim

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

} 

? Aynı sonucu elde etmenin başka bir yolu var mı?

Kısa bir ek: NetBeans'in otomatik tamamlama özelliği tarafından görülmesini sağlamak için sınıftaki özniteliklerini bildiriyorum.

+1

[PHP 5.2'deki sınıf devralma sınıfının muhtemel mirası: olası uzantı sınıfında geçersiz değişken mi?] (Http://stackoverflow.com/questions/3017777/class-inheritance-in -php-5-2-overriding-static-variable-in-extension-class) – outis

+0

Bu oldukça kafa karıştırıcı bir uygulamaya sahip olan php'de yasal bir sorudur, ancak soru daha genel ve erişilebilir hale getirmek için gerçekten daraltılmış olabilir. diğer insanlar yararına. –

cevap

41

Late Static Binding adlı kullanıcıyı arıyor.

static::$databaseTable 

yerine Bu özellik PHP 5.3'ten kullanılabilir

self::$databaseTable 

ait:

Yani kullanmak gerekir. PHP 5.2'de bunu simule etmek iki sebepten dolayı çok zordur: get_called_class sadece PHP 5.3'ten beri kullanılabilir. Bu nedenle, debug_backtrace kullanarak da simüle edilmelidir. İkinci sorun şu ki, eğer çağrılan sınıfınız varsa, $calledClass::$property'u kullanmaya devam edebilirsiniz, çünkü bu bir PHP 5.3 özelliği. Burada eval veya Reflection'u kullanmanız gerekir. Bu yüzden, PHP 5.3'e sahip olduğunuzu umuyorum;)

+0

Ne yazık ki, PHP sürümümü yükseltemiyorum. Sunucu sadece 5.2.13'ü destekleyen Plesk 9.5'i çalıştırıyor; El ile yükseltmekten korkuyorum, bazı uygulamaları bozabilir. Aynı işi yapmak için alternatif bir yol tasarlayabilir miyim? – DfKimera

+0

Bu ipucu için çok teşekkür ederim, bende aynı problem vardı! –

+0

En iyi yol, sınıfın bu özelliklere erişmesi gereken herhangi bir yönteme ilk parametre olarak geçirilmesini içerir. Bu şekilde, bu sınıfı doğrudan bir geçersiz kılma için arayabilirsiniz. Bulunmazsa, alanı bulana kadar üst merdivenden yukarı çıkabilirsiniz. –

İlgili konular