2010-08-02 111 views
0

讓我們來看看我是否可以正確描述這個...PHP5和抽象類。爲每個子類分別提供類變量副本?

我有一個抽象類,當其他類從它擴展時,我想抽象類的數據被重置爲零。

這個想法是我有一堆類擴展這個和使用MySQL表的數據結構。我不想用每個類實例化查詢數據庫來確定類的數據(「來自tablename的SHOW COLUMNS」)

因此,對於每個類,我希望它對每個「我們創建了這個類之前?如果是這樣,我們知道班級的結構,如果沒有,抓住表格列並創建班級以及存儲表格列供以後使用。「

我一直在使用以下來測試我的想法:

$columns = array("Column 1", "Column 2", "Column 3"); 

abstract class AbstractClass { 

    protected static $colFields = array(); 

    public function __construct() { 
     $this->setVars(); 
    } 

    private function setVars() { 
     global $columns; 
     if (count(self::$colFields) == 0) { 
      var_dump("Array length is 0"); 
      foreach ($columns as $key) { 
       self::$colFields[] = $key; 
       if (!isset($this->$key)) 
        $this->$key = null; 
      } 
     } 
     else { 
      var_dump("Array length is not 0"); 
      foreach (self::$colFields as $key) { 
       $this->$key = null; 
      } 
     } 
    } 

    public function test() { 
     var_dump($this); 
    } 

} 

class ObjectA extends AbstractClass {}; 

class ObjectB extends AbstractClass {}; 


$objectAA = new ObjectA(); 
$objectAB = new ObjectA(); 
$objectAC = new ObjectA(); 

$objectAC->test(); 

$objectBA = new ObjectB(); 
$objectBB = new ObjectB(); 
$objectBC = new ObjectB(); 

$objectBC->test(); 

和腳本的輸出是:

串(17)的 「陣列長度被0」
串(21)的 「陣列長度不爲0」
串(21)的「陣列長度不是0「
對象(對象A)#3(4){
[ 「的className」:保護] =>
串(7) 「對象A」
[ 「列1」] =>
NULL
[「第2列「] =>
NULL
[」 列3" ] =>
NULL
}
串(21)的 「陣列長度不爲0」
串(21)的 「陣列長度不爲0」
string(21)「Array length is not 0」
對象(對象B)#6(4){
[ 「的className」:保護] =>
串(7) 「對象B」
[ 「列1」] =>
NULL
[「列2 「] =>
NULL
[」 列3" ] =>
NULL
}

我期待對象B的第一實例以輸出 「陣列長度爲0」 段,然後繼續。

任何人都可以幫忙嗎?

+0

在我看來,這是繼承是一個不好的方式來處理數據庫訪問的原因之一。 – 2010-08-02 21:15:23

+0

是的,我現在有工作很好,每個類實例化查詢表的列,但一如既往,我想減少數據庫查詢的數量。 – Charlie 2010-08-02 21:18:47

回答

4

我建議你不要在你的抽象類中存儲緩存的表信息。創建一個名爲TableInformationRepository的類或類似的東西。讓您的子類或抽象類查詢TableInformationRepository以獲取有關表/類的信息。在TableInformationRepository中,緩存你想要按類名或表名鍵入的信息。

+0

我正在考慮走這條路線,我可能不得不這樣做。 將大型數組/對象中的所有表定義存儲就不那麼優雅。 :/ – Charlie 2010-08-02 21:24:05

0

要添加到什麼斯科特桑德斯說 - 爲什麼不使用單身呢?

http://php.net/manual/en/language.oop5.patterns.php - 例如#2

+0

我必須玩這個......我只是實現了一個基本的緩存thingy像斯科特建議,但我將不得不看看這個... – Charlie 2010-08-02 21:39:51

+0

我會建議多倍。這與單身人士相關,但不是每個人都很常見。它允許多一個實例。這樣你可以控制每個db-table有一個實例。 – 2010-08-02 22:07:54

+0

更好的信息。多謝你們!已經在研究這一個。 – Charlie 2010-08-02 23:10:15

0

在PHP中,如果不重新聲明在子類中受保護/公共靜態字段,它們都將屬於同一個參考集。這意味着受保護財產的變化將反映在所有的類別中。

例子:

class A { 
    public static $field = "1"; 
} 
class B extends A { } 
B::$field = 2; 
echo A::$field; //2 

在另一方面:

class A { 
    public static $field = "1"; 
} 
class B extends A { 
    public static $field = "1"; 
} 
B::$field = 2; 
echo A::$field; //1 

你也可以打破基準手動設置:

class A { 
    public static $field = "1"; 
} 
class B extends A { } 
$v = 2; 
B::$field = &$v; 
unset($v); 
echo A::$field; //1