2010-06-10 99 views
11

我需要能夠使用一個靜態變量設置在擴展基類的類中...從基類。PHP 5.2中的類繼承:在擴展類中重寫靜態變量?

考慮一下:

class Animal { 
    public static $color = 'black'; 

    public static function get_color() 
    { 
     return self::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 
} 

echo Animal::get_color(); // prints 'black' 
echo Dog::get_color(); // also prints 'black' 

這奇妙的作品在PHP 5.3.x(Dog::get_color()打印 '棕'),因爲它具有後期靜態綁定。但我的生產服務器運行PHP 5.2.11,所以我需要修改我的腳本。

是否有幾分姿色的解決方法來解決這個問題?

乾杯!
克里斯托弗

編輯:我們的目標

如下文所述,這是什麼,我試圖完成一個很簡單的例子。如果我爲你提供我已經習慣瞭解決我的問題的兩個選項(和問題本身)的人可能比我不同的解決方案......

我已經建立了一個包含樣功能的基礎數據庫模型「發現」 ,「find_by」和「find_all」(全部是靜態的)。

在PHP 5.3中有一個叫做get_called_class()的函數,我目前使用它來確定被調用類的名字,然後用它來映射正確的數據庫表。 Ex類User將指向users

get_called_class()不PHP 5.2.x存在,黑客實現我發現是非常不可靠的。然後我轉向在包含類名的所有模型類中使用靜態變量的選項。

+1

我想'Dog'應該擴展'Animal'? – 2010-06-10 19:41:25

+0

你是絕對正確的:) – Christoffer 2010-06-10 19:42:04

+1

隨着進一步的解釋,我認爲你應該把你的find/find函數看作是一個表類的方法而不是行類的靜態方法(這聽起來像是你正在嘗試的結果 – gnarf 2010-06-11 16:29:46

回答

2

可悲的是,PHP 5.3之前,有沒有辦法來模擬後期靜態綁定。您可以按照您的意圖獲得繼承的唯一方法是如果這些是實例變量和方法。

+0

這意味着我不能使用靜態方法來創建對象本身嗎? – Christoffer 2010-06-10 19:38:41

+1

如果您依賴存儲的靜態數據在子類中,編號 – VoteyDisciple 2010-06-10 20:19:28

9

我繼承Zend Framework中的東西時,就遇到了這個問題。我的判斷是,在純靜態的土地,你只有一個選擇......在繼承類重新定義函數:

class Animal { 
    public static $color = 'black'; 

    public static function get_color() 
    { 
     return self::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 

    public static function get_color() 
    { 
     return self::$color; 
    } 
} 

如果你能夠創建實例 - 您可以使用get_class($this)找出調用類,例如:

class Animal { 
    public static $color = 'black'; 

    public function getColor() // note, not static 
    { 
     $class = get_class($this); 
     return $class::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 
} 

$animal = new Animal(); 
echo $animal->getColor(); // prints 'black' 
$dog = new Dog(); 
echo $dog->getColor(); // prints 'brown' 

我想用一個函數參數的靜態函數定義一個類它被稱爲從的唯一選擇。它可以默認爲__CLASS__,然後你可以從子類中選擇return parent::get_class($class)。這樣的模式可以用來重新使用靜態函數更容易(因爲我疑惑返回一個公共靜態屬性是你想要在一個靜態方法來使用self::的唯一的事情做:

class Animal { 
    public static $color = 'black'; 

    public static function get_color($class = __CLASS__) 
    { 
     // Super Simple Example Case... I imagine this function to be more complicated 
     return $class::$color; 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 

    public static function get_color($class = __CLASS__) 
    { 
     return parent::get_color($class); 
    } 
} 
+1

謝謝你的回答,它在我提供的例子中有效,但是實際情況比較複雜一點,我編輯我的帖子告訴你我真正想要做什麼,希望可能會有很多不同於我嘗試過的角度。 – Christoffer 2010-06-11 06:07:43

5

在PHP 5。3+,下面將是首選:

class Animal { 
    public static $color = 'black'; 

    public static function get_color() 
    { 
     return static::$color; // Here comes Late Static Bindings 
    } 
} 

class Dog extends Animal { 
    public static $color = 'brown'; 
} 

echo Animal::get_color(); // prints 'black' 
echo Dog::get_color(); // prints 'brown' 

Late Static Bindings (PHP.net)