¿Herencia de clase en PHP 5.2: reemplazando a la variable estática en la clase de extensión?

Necesito poder usar un conjunto de variables estáticas en una clase que amplíe una clase base … desde la clase base.

Considera esto:

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' 

Esto funciona maravillosamente en PHP 5.3.x ( Dog::get_color() imprime ‘marrón’) ya que tiene enlace estático tardío. Pero mi servidor de producción ejecuta PHP 5.2.11 y entonces necesito adaptar mi script.

¿Hay alguna solución bastante bonita para resolver este problema?

¡Aclamaciones!
Christoffer

EDITAR: El objective

Como se señala a continuación, este es un ejemplo muy simplificado de lo que estoy tratando de lograr. Si le proporciono las dos opciones que he usado para resolver mi problema (y el problema en sí) alguien podría tener una solución diferente a la que yo …

Creé un modelo de base de datos que contiene funciones como “buscar”, “buscar_by” y “buscar_todos” (todo estático).

En PHP 5.3 hay una función llamada get_called_class() que actualmente utilizo para determinar el nombre de la clase llamada, y luego la utilizo para mapear con la tabla correcta de la base de datos. User clase ex apuntaría a los users .

get_called_class() no existe en PHP 5.2.x y las implementaciones de hackeo que he encontrado son muy poco confiables. Luego recurrí a esta opción de usar una variable estática en todas las clases de modelos que contienen el nombre de la clase.

Lamentablemente, antes de PHP 5.3 no hay forma de simular el enlace estático tardío. La única forma en que puede lograr que la herencia funcione como lo desea es que esas sean variables y métodos de instancia.

Me encontré con este problema cuando subclassing algo en el Zend Framework. Mi determinación fue que en un terreno puramente estático, solo tienes una opción … Redefine la función en la clase heredada:

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

Si puede crear instancias: puede usar get_class($this) para averiguar la clase de llamada, por ejemplo:

 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' 

La única otra opción en la que pensé fue usar un parámetro de función para la función estática para definir una clase desde la que se estaba llamando. Puede establecer el valor predeterminado de __CLASS__ y luego puede return parent::get_class($class) de la subclase. Un patrón como este podría usarse para facilitar la reutilización de la función estática (ya que dudo que devolver una propiedad estática pública sea lo único que está intentando usar self:: for en ese método estático:

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

En PHP 5.3+, se preferiría lo siguiente:

 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' 

Enlaces estáticos tardíos (PHP.net)