2011-06-01 15 views
6

Estaba trabajando en PHP alrededor de la palabra clave "static ::", y encontré un problema donde demasiadas llamadas estáticas producen confusión en cuanto a dónde reside un método. Es más fácil mostrar por ejemplo:Posible error de PHP alrededor de estática :: en PHP 5.3.3

class Class1 
{ 
    function Test() 
    { 
     return Class2::Test(); 
    } 
} 

class Class2 
{ 
    function Test() 
    { 
     return static::Test2(); 
    } 

    function Test2() 
    { 
     return true; 
    } 
} 

/* test 1: calling Class1::Test() statically results in expected call to Class2::Test2() */ 
echo "test 1: " . Class1::Test() . "\n"; 

/* test 2: instantiating the class causes Class1::Test2() to be called, which does not exist */ 
$Class1 = new Class1(); 
echo "test 2: " . $Class1->Test() . "\n"; 

quería alcanzar y obtener opiniones de los expertos en php que me puede decir si esto podría ser un error genuino o sencilla mal uso del lenguaje.

Me doy cuenta de que la configuración puede ser extraña con todas las llamadas estáticas, pero representa el código real que encontré.

Háganme saber si necesita más información o aclaración. Gracias por cualquier ayuda de antemano!

+1

¿qué versión de PHP estás usando? la palabra clave estática no se extendió hasta 5.3 –

+0

Creo que está preguntando si esto es realmente un error con la palabra clave estática y cómo se supone que todo el enlace estático final "funciona". – LLBBL

+0

Olvidé mencionar, ejecutando 5.3.3 –

Respuesta

7

Los documentos de PHP en late static bindings responden a su pregunta.

"fijaciones finales estáticos funcionan mediante el almacenamiento de la clase mencionada en la última 'llamada no reenvío'. En el caso de las llamadas a métodos estáticos, esta es la clase llamada explícita (por lo general el de la izquierda de la :: operador); en el caso de llamadas a métodos no estáticos, es la clase del objeto. Una "llamada de reenvío" es una estática que es introducida por self ::, parent ::, static :: "...

Su prueba 1 es una llamada estática, por lo que cuando se llama a Class2::Test(), almacena Class2. La llamada de test2 estática se refiere al lugar correcto en Class2.

Su prueba 2 es una llamada no estática, por lo que utiliza la clase del objeto en todos los casos, y dado que es Class1, no puede encontrar el método Test2.

+0

Gracias por la referencia, puedo ver que describen específicamente esta instancia en la documentación. Sin embargo, ahora tengo que preguntarme si esto es un error que debería ser reportado. ¿Pensamientos? –

+0

@Jeff ¿Por qué sería un error? Parece que esto es exactamente lo que pretendían. ¿Qué comportamiento esperarías y por qué es más correcto? (También tendrías que explicarles eso en un informe de error). – Tesserex

+0

Primero, me disculpo por no estar tan versado en el funcionamiento interno de PHP como muchas personas aquí. En mi ejemplo, se esperaba que el código obtuviera el resultado de Class2 :: Test2() por $ Class1-> Test() -> Class2 :: Test() -> Class2 :: Test2(). ¿Es esto una expectativa razonable? –