miércoles, 19 de marzo de 2008

Problemas al acceder al nombre de la clase en un esquema de herencia desde metodos estaticos en PHP

Digamos que tenemos un esquema como el siguiente, en donde hay dos clases que mantienen una relación de herencia, y hay un método estático definido en la clase padre, el cual accede al nombre de la clase y es invocado por la clase hija. El resultado esperado sería que el nombre de la clase fuera el de la clase hija, pero como veremos en el ejemplo, el resultado es la clase padre.
class A {
public static function
who() {
echo
__CLASS__;
}
public static function
test() {
self::who();
}
}

class
B extends A {
public static function
who() {
echo
__CLASS__;
}
}

B::test();

Lo descrito anteriormente sucede porque PHP resuelve el nombre de la clase por la clase a la cual pertenece el método que se está invocando, lo que tal vez se puede ver como una violación al polimorfismo, es decir, que esperamos que el código anterior devuelva el nombre de la clase sobre la cual es invocado el método, pero no es así.

Según el manual de PHP, con la versión 5.3.0 este tema será resuelto de forma nativa por PHP, la solución a este problema lleva el nombre de "Late Static Bindings". Lo que básicamente agrega esta solución es una palabra clave que ayuda a referenciar a la clase correcta en tiempo de ejecución conservando el comportamiento deseado en un ambiente Orientado a Objetos con polimorfismo. Este es el ejemplo que se ofrece en la documentación de PHP:

class A {
public static function
who() {
echo
__CLASS__;
}
public static function
test() {
static::
who(); // Here comes Late Static Bindings
}
}

class
B extends A {
public static function
who() {
echo
__CLASS__;
}
}

B::test();


En este ejemplo se agrega la palabra clave "static" para referenciar a la clase correcta en tiempo de ejecución, devolviendo el valor correcto y esperado para un ambiente que soporta polimorfismo.

Por más información sobre el tema, accede al manual de PHP - Late Static Bindings.

No hay comentarios:

Publicar un comentario en la entrada