2011-04-01 6 views
12

Código rápido con la pregunta incluye:Variables estáticas de PHP en una clase principal abstracta: ¡la pregunta está en el código de muestra!

abstract class ClassParent { 
    public static $var1 = "ClassParent"; 
} 

class ClassChild1 extends ClassParent{ 
    public static function setvar1(){ 
     ClassChild1::$var1 = "ClassChild1";  
    } 
} 

class ClassChild2 extends ClassParent{ 
    public static function setvar1(){ 
     ClassChild2::$var1 = "ClassChild2"; 
    } 
} 


ClassChild1::setvar1(); 

echo ClassChild2::$var1; 
// Returns "ClassChild1". Shouldn't this still be "ClassParent"? 

Estoy suponiendo que el comportamiento que se espera arriba y no un error de PHP. En ese caso, ¿cómo podría declarar una variable estática en la clase principal que se manejará por separado para las clases secundarias? En otras palabras, quiero tener valores estáticos separados POR CLASE DE NIÑO. ¿Debo declarar la variable estática específicamente en las clases para niños o quizás haya otra manera?

Gracias!

Respuesta

16

EDITAR: En una investigación más profunda, creo que lo que está preguntando no es posible directamente, incluso con encuadernación estática tardía. En realidad, estoy un poco sorprendido.

The answer to this question proporciona algunas soluciones.

Respuesta original:


En una clase padre, si se hace referencia a una variable estática en la forma:

self::$var 

Se utilizará esa misma variable en todas las clases heredadas (por lo que todo las clases secundarias seguirán accediendo a la variable en la clase principal).

Esto se debe a que el enlace para la palabra clave self se realiza en tiempo de compilación, no en tiempo de ejecución.

A partir de PHP 5.3, PHP admite la vinculación estática tardía, utilizando la palabra clave static. Así, en sus clases, se refieren a la variable con:

static::$var 

Y 'estática' se resolverá a la clase de niño en tiempo de ejecución, por lo que habrá una variable estática independiente para cada clase hija.

+0

Gracias por la respuesta. Estoy usando 5.3. Esto no debería ser diferente de lo que codifiqué anteriormente: simplemente expuse explícitamente el nombre de clase en lugar de usar 'estático'. Y de hecho, cambiarlos a estáticos produce el mismo resultado. – Aron

+0

... lo único que parece funcionar es si declaro explícitamente la variable en la clase hija. Pero, si es posible, me gustaría evitar esta solución ... – Aron

+0

Cuando publiqué mi respuesta, su fragmento de código no estaba completo. No creo que haya una solución limpia para esto. Actualicé mi respuesta con más información. – Lauren

3

Gracias por esta pregunta! Tuve algunos problemas que no pude rastrear y esto me ayudó a resolverlos. :)

Puede que le interese saber que hay un bug report para este comportamiento que incluye la solución. En su caso esto sería:

class ClassChild1 extends ClassParent{ 
    public static function setvar1(){ 
     $tmp = 'x'; 
     static::$var1 =& $tmp; // break reference 
     // and now this works as expected: (changes only ClassChild1::$var1) 
     static::$var1 = "ClassChild1";  
    } 
} 
// do the same in ClassChild2... 

feo como el infierno, estoy de acuerdo - pero PHP funciona como se espera de esta manera, además de que no tiene efectos secundarios.

Esto es de hecho una "característica" muy dudosa (y mal documentada) en mis ojos, esperemos que algún día cambien.

+1

Tenga en cuenta que esto fue declarado como "No es un error". Incluso si es una característica, debe documentarse :). –

+0

Bueno, 'magic_quotes' y' safe_mode' tampoco eran errores, pero me alegré cuando se los quitaron. ;) Los desarrolladores de PHP tienen una historia de algunas (en mi opinión, por supuesto) malas decisiones de diseño y esta es ciertamente una de ellas (de nuevo: IMnsHO). – johndodo

+0

Estoy esperando (no he probado) que redeclar el $ var1 como una estática en ambas subclases también debería hacer el trabajo. Y sería muchísimo menos feo;) –

Cuestiones relacionadas