miércoles, 17 de febrero de 2010

API Reflection

API Reflection nos permite básicamente hacer ingeniería inversa de nuestras clases, pudiendo ver así a sus métodos, atributos, constructores, ya sean públicos o privados, etc. De esta manera por ejemplo, una clase puede conocerse a si misma y hacer cosas que sin API Reflection no se podrían. Esto no sólo se aplica a clases, sino que también es posible con interfaces, funciones, etc.
API Reflection no es muy conocida, pero es utilizada para varias cosas, como por ejemplo para generar documentación de código (como phpDoc) o generar XML Schemas a partir de clases, etc.

PHP nos ofrece una serie de clases para utilizar API Reflection, vamos a ver algunas de ellas.

Con la clase ReflectionClass, podemos hacer ingeniería inversa de una clase, accediendo al nombre de la clase, sus modificadores, métodos, propiedades, etc.

Instanciamos un objeto ReflectionClass, pasándole como parámetro al constructor el nombre de la clase sobre la cual vamos a hacer ingeniería inversa:

$clase = new ReflectionClass(“LaClase”);
Ya está, saquemos algo de información sobre la clase:

echo “Nombre de la clase: ” . $clase->getName() . “n”;
echo “La clase es abstracta? ” . $clase->isAbstract() . “n”;
echo “La clase es final? ” . $clase->isFinal() . “n”;

Si queremos obtener los métodos que tiene la clase, podemos utilizar el método getMethods() que tiene ReflectionClass:

$metodos = $clase->getMethods();
Nos devuelve un array de objetos ReflectionMethod. Que como podrán imaginar son los métodos de la clase. Con los métodos de ReflectionMethod podemos hacer ingeniería inversa de los métodos:

foreach($metodos as $metodo) {
echo “Es público?” . $metodo->isPublic() . “n”;
echo “Es estático?” . $metodo->isStatic() . “n”;
echo “Es abstracto?” . $metodo->isAbstract() . “n”;
echo “Es un constructor?” . $metodo->isConstructor() . “n”;
}

Si queremos obtener las propiedades de la clase, podemos utilizar getProperties():

$propiedades = $clase->getProperties();
Nos devuelve un array de objetos ReflectionProperty, lo cual nos permite hacer ingeniería inversa de las propiedades:

foreach($propiedades as $propiedad) {
echo “Nombre de la propiedad: ” . $propiedad->getName() . “n”;
echo “Es pública?” . $propiedad->isPublic() . “n”;
echo “Es estática?” . $propiedad->isStatic() . “n”;
}
Podemos utilizar los métodos hasMethod() o hasProperty() para saber si una clase tiene determinado método o propiedad:

echo “La clase tiene el método unMetodo? ” . $clase->hasMethod(“unMetodo”) . “n”;
echo “La clase tiene la propiedad unaPropiedad? ” . $clase->hasProperty(“unaPropiedad”) . “n”;
En este caso hicimos ingeniería inversa de una clase, y con los métodos getMethods() y getProperties() obtuvimos los objetos ReflectionMethod y ReflectionProperty para cada uno de los métodos y propiedades. Pero también podemos hacer ingeniería inversa de un método o una propiedad directamente, instanciando ReflectionMethod / ReflectionProperty pasándole al constructor directamente el nombre de la clase y del método / propiedad a hacer ingeniería inversa:

>$metodo = new ReflectionMethod(“UnaClase”, “unMetodo”);
$propiedad = new ReflectionProperty(UnaClase”, “unaPropiedad”);
En caso de querer hacer ingeniería inversa de una función, en vez de un método, se utiliza ReflectionFunction:

$funcion = new ReflectionFunction(“unaFuncion”);
Tanto ReflectionMethod como ReflectionFunction, tienen un método getParameters() que devuelve un array de objetos ReflectionParameter con todos los parámetros de la función o método:

$parametros = $funcion->getParameters();
Con ReflectionParameter, podemos hacer ingeniería inversa de los parámetros de una función o método:

foreach($parametros as $parametro) {
echo “Nombre del parámetro: ” . $parametro->getName() . “n”;
echo “Es opcional?: ” . $parametro->isOptional() . “n”;
}
Bueno, como podrán ver, es bastante sencillo de usar. Lo mejor como siempre, es consultar la documentación oficial de PHP sobre API Reflection.

No hay comentarios:

Publicar un comentario