2010-06-10 18 views
11

Necesito poder usar un conjunto de variables estáticas en una clase que amplíe una clase base ... desde la clase base.Herencia de clases en PHP 5.2: Anulación de variables estáticas en la clase de extensión?

Considera:

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 de maravilla en PHP 5.3.x (Dog::get_color() imprime 'marrón'), ya que tiene fines de enlace estático. 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?

¡Salud!
Christoffer

EDIT: El objetivo

Como se señala más adelante, 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 mismo), alguien podría tener una solución diferente a la que ...

He creado un modelo de base de datos que contiene funciones como "buscar" , "find_by" y "find_all" (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. La clase Ex User apuntaría al 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.

+1

Asumo '' Dog' debe extenderse Animal'? –

+0

Tiene toda la razón :) – Christoffer

+1

Con las explicaciones adicionales, creo que debe poner su find/find por funciones como métodos en una clase de tabla en lugar de statics en una clase de fila (que es lo que parece que está intentando – gnarf

Respuesta

2

Lamentablemente, antes de PHP 5.3 no hay manera de simular la vinculación estática tardía. La única forma en que puede lograr que la herencia funcione como lo desea es que esas sean variables y métodos de instancia.

+0

¿Qué significa que no puedo usar métodos estáticos para crear los objetos? – Christoffer

+1

No si confía en datos estáticos almacenados en subclases, No. – VoteyDisciple

9

Me encontré con este problema al crear una subclase de algo en Zend Framework. Mi determinación fue que en la tierra puramente estático, que sólo tiene una opción ... redefinir la función en la clase que hereda:

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 usted es capaz de crear instancias - Se 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 que pensé fue el uso de un parámetro de la función a la función estática para definir una clase que estaba siendo llamado desde. Puede establecerse por defecto en __CLASS__ y luego puede return parent::get_class($class) en la subclase. Un modelo de este tipo podría ser utilizado para hacer volver a utilizar la función estática más fácil (como dudo devolver una propiedad estática pública es el único que está intentando utilizar self:: en dicho 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); 
    } 
} 
+1

Gracias por su respuesta. Funciona en el ejemplo que proporcioné, pero el caso real es un poco más complicado. Edito mi publicación para decirle lo que realmente quiero hacer y espero que pueda haber muy diferentes ángulos que los que he probado. – Christoffer

5

En PHP 5.3+, se preferiría la 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' 

Late Static Bindings (PHP.net)

Cuestiones relacionadas