2010-07-21 16 views
14

यह मेरे पास है: डेटाबेस पर बने सभी ऑब्जेक्ट्स डेटाबेस ऑब्जेक्ट अमूर्त वर्ग का विस्तार करते हैं, जिसमें वास्तव में विशेषता परिवर्तनों के लिए देखने के लिए सभी तर्क कोड होते हैं और डेटाबेस क्वेरी चलाते हैं।किसी ऑब्जेक्ट ऑब्जेक्ट की स्थिर संपत्ति को ओवरराइड कैसे करें और पैरेंट में ऑब्जेक्ट को नए मान तक पहुंचने दें?

मैं ऑब्जेक्ट-विशिष्ट विवरण को परिभाषित करने के लिए दो स्थैतिक चर का उपयोग कर रहा हूं। मैं उन्हें सामान्य रूप से बेस क्लास में परिभाषित करता हूं, और फिर माना जाता है कि मैं उन्हें वास्तविक डेटाबेस ऑब्जेक्ट्स में ओवरराइट करता हूं।

समस्या यह है: जब मूल वर्ग में कोड वास्तव में निष्पादित किया जाता है, तो यह वर्तमान ऑब्जेक्ट मान के बजाय पुराने मूल मान का उपयोग करता है।

यहाँ आधार वर्ग के लिए कोड है:

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

} 

क्या मैं गलत यहाँ कर रहा हूँ? क्या एक और तरीका है जिससे मैं एक ही परिणाम प्राप्त कर सकता हूं?

एक संक्षिप्त परिशिष्ट: मैं मुख्य रूप से नेटबीन की ऑटो-पूर्ण सुविधा द्वारा इसे देखने के लिए कक्षा निकाय में विशेषताओं की घोषणा करता हूं।

+1

संभवतः डुप्लिकेट [PHP 5.2 में कक्षा विरासत: विस्तार वर्ग में स्थिर चर को ओवरराइड करना?] (Http://stackoverflow.com/questions/3017777/class-inheritance-in -php-5-2-overriding-static-variable-in-extension-class) – outis

+0

यह php में एक कानूनी प्रश्न है, जिसमें एक बहुत भ्रमित कार्यान्वयन है, लेकिन प्रश्न को अधिक सामान्य और सुलभ बनाने के लिए वास्तव में संकुचित किया जा सकता है अन्य लोगों के लिए लाभ उठाने के लिए। –

उत्तर

41

आप Late Static Binding के लिए देख रहे हैं।

static::$databaseTable 

बजाय

self::$databaseTable 

यह सुविधा पीएचपी 5.3 के रूप में उपलब्ध है:

तो आप का उपयोग करने की आवश्यकता है। PHP 5.2 में इसे सिमुलेट करना बहुत मुश्किल है, दो कारणों से: get_called_class केवल PHP 5.3 के बाद ही उपलब्ध है। इसलिए इसे debug_backtrace का उपयोग करके भी अनुकरण किया जाना चाहिए। दूसरी समस्या यह है कि यदि आपके पास कॉल क्लास है, तो भी आप $calledClass::$property का उपयोग नहीं कर सकते क्योंकि यह एक PHP 5.3 सुविधा भी है। यहां आपको eval या Reflection का उपयोग करने की आवश्यकता है। इसलिए मुझे उम्मीद है कि आपके पास PHP 5.3 है;)

+0

दुर्भाग्य से, मैं अपने PHP संस्करण को अपग्रेड नहीं कर सकता। सर्वर Plesk 9.5 चला रहा है, जो केवल 5.2.13 तक का समर्थन करता है; मुझे मैन्युअल रूप से अपग्रेड करने का डर है कि यह कुछ प्रशंसा तोड़ सकता है। मैं देखता हूं कि क्या मैं एक ही कार्य करने का वैकल्पिक तरीका तैयार कर सकता हूं। – DfKimera

+0

इस टिप के लिए आपको बहुत बहुत धन्यवाद, मुझे एक ही समस्या थी! –

+0

सबसे अच्छा तरीका क्लास को किसी भी विधि के पहले पैरामीटर के रूप में पास करने में शामिल है जिसमें इन गुणों तक पहुंचने की आवश्यकता है। इस तरह, आप सीधे उस ओवरराइड के लिए उस कक्षा को खोज सकते हैं। यदि नहीं मिला, तो आप फ़ील्ड को ढूंढने तक पैरेंट सीढ़ी तक जा सकते हैं। –

संबंधित मुद्दे