Наследование класса в 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, поэтому мне нужно адаптировать мой скрипт.

Есть несколько довольно обходной путь для решения этой проблемы?

Ура!
Кристоффер

EDIT: Цель

Как отмечено ниже, это очень упрощенный пример того, что я пытаюсь выполнить. Если я предоставил вам два варианта, которые я использовал для решения моей проблемы (и сама проблема), у кого-то может быть другое решение, чем у меня …

Я создал базовую модель базы данных, которая содержит такие функции, как «find», «find_by» и «find_all» (все статические).

В PHP 5.3 существует функция, называемая get_called_class() которую я использую в настоящее время для определения имени вызываемого класса, а затем используйте ее для сопоставления с соответствующей таблицей базы данных. User Ex class User укажет на users .

get_called_class() не существует в PHP 5.2.x, и реализованные get_called_class() реализации hack очень ненадежны. Затем я обратился к этому варианту использования статической переменной во всех классах моделей, которые содержат имя класса.

К сожалению, перед PHP 5.3 невозможно смоделировать позднюю статическую привязку. Единственный способ заставить наследование работать так, как вы намереваетесь, – это те переменные и методы экземпляра.

Я столкнулся с этой проблемой при подклассификации чего-то в 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:: in в этом статическом методе:

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

В 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' 

Поздние статические привязки (PHP.net)