Encontrar donde se define una clase usando el nombre de la clase

En un proyecto en el que me encuentro trabajando surgió la necesidad de implementar un módulo para OAuth, tenía que bajar el módulo y comenzar a usarlo. Cuando quiero comenzar a usarlo me salta un error que la clase OAuthException ya había sido declarada previamente.

Lo primero que se me vino a la mente es que el archivo que tenía la clase estaba siendo incluido mas de una vez, cuando me pongo a debuggear no era el caso, el archivo no estaba siendo incluido mas de una vez.

Lo segundo que pienso es que la clase estaba definida en algún otro módulo, así que grepeo todo el fuente del proyecto para buscar la definición de la clase en otro lado, el resultado fue que no había otra definición, solo la del módulo que acababa de instalar.

Después de mucho buscar y buscar, se me vino a la mente de buscar donde estaba el archivo en función del nombre de la clase, googleando un poco me encontré en stackoverflow con la clase ReflectionClass la cual posee varios métodos interesantes, entre ellos el método getFileName, este a partir del string con el nombre de la clase devuelve el path al archivo donde la clase fue definida. Aquí un ejemplo

$reflector = new ReflectionClass('Foo');
echo $reflector->getFileName();

Ya estamos dije yo, cuando corro esto para ver que me decía mi sorpresa vino de que este me devolvía vacío. Pensando un poco mas me doy cuenta que si la clase es parte de una extensión o nativa de PHP difícilmente este en un archivo, así me encontré con este otro método de la misma clase, isInternal, el cual me dio verdadero.

Con eso me saque la duda de donde venía la clase, el paso siguiente fue revisar mi lista de extensiones y me encontré con que tenía una extensión pecl para oauth (la cual instalé para otro proyecto hace bastante) y la misma definía una clase con el mismo nombre, algo que no debería pasar en las nuevas versiones de PHP si usamos espacios de nombre.

Para solucionarlo desactive la extensión y seguí codeando.

 

Share

Instalar Runkit en Debian

Tengo que escribir este post mas que nada para acordarme que carajo hice para instalar Runkit. Runkit es una extensión de PHP que permite modificar los simbolos del interprete en tiempo de ejecución, que significa esto, basicamente que puedo modificar el valor de las constante, redefinir variables globales, modificar el comportamiento de las funciones, metodos objetos y otras cosas del entorno en tiempo de ejecución. La pregunta del millon de dolares es para que carjo quiero hacer algo tan descabellado, la respuesta es sencilla, estoy viendo como poder hacer mocks de funciones y para ello necesito poder, en tiempo de ejecución, modificar las funciones previamente definidas para injectar el mock de la misma. Moraleja, esta extensión es bastante prohibida y no debería utiliarse nunca, no se les ocurran andar instalandola para hacer sistemas de producción.

Bueno, estuve peleando toda la tarde con la Mac roñosa que me dan en el laburo para poder compilar esta extensión, logre compilarla pero la extensión quedo pinchada, tira segmentation fault por todos lados, voy a escribir otro post para cuando la tenga funcionando posta. Pensé que en mi Linux iba a funcionar de una pero me encontré con que tampoco se podía compilar tan fácilimente, aparentemente el build de PECL esta pinchado y no funciona bien con PHP 5.3 en Debian y derivados, pero hay un santo que se tomo el trabajo de hacer una versión que funciona.

Los pasos de instalación son sencillos.

#wget https://github.com/zenovich/runkit/zipball/master

#unzip tcz-phpunit-mockfunction-{hashcambia}.zip

#cd tcz-phpunit-mockfunction-{hascambia}

#phpize

#./configure

#make

#make install

Si todo salio sin errores el último paso es habilitar la extensión, en el caso normal consta con añadir la regla extension=runkit.so al php.ini; como en los debians se mantiene una conf separada para  el interprete de la linea de comandos (cli) y el apache la mejor opcion es añadir un archivo runkit.conf en el directorio /etc/php5/conf.d con la linea para incluir la extension.

# echo ‘extension=runkit.so’> /etc/php5/conf.d/runkit.conf

Para testear si esta funcionando

echo ‘extension=runkit.so

% php –info|grep runkit

/etc/php5/cli/conf.d/runkit.ini,

runkit

runkit support => enabled

runkit.internal_override => Off => Off

runkit.superglobal => no value => no value

Si aparecer support enabled esta funcionado. Voy a seguir trabajando sobre esto y voy a ir posteando mas cosas al respecto de este viaje que estoy haciendo sobre esta extensión.
Links de interes
Share

Drupal, Caracteres no alfanuméricos en el string de conexión

Hoy me paso algo muy curioso, me crearon una base de datos que iba a utilizar con Drupal6 y la password que me dieron era una cosa así “{{==+aa+2fz.”, rara pero totalmente válida para MySQL.

Cuando seteo el string de conexión de Drupal y quiero ver si funciona el sitio obtengo un error de acceso denegado al MySQL, pruebo conectarme desde la shell con esa password y no hubo problemas. Me puse a investigar cual puede ser el problema y veo que Drupal para parsear el string de conexión utiliza la función parse_url por ende alguno caracteres como . + = @ entre otros puede traer problemas. La solución, fácil, pasar la contraseña por un urlencode para que reemplaze los caracteres especiales de la contraseña como percent-encoding ( o realizar el cambio a mano), por ende la contraseña debería quedar así

{{==+aa+2fz. => %7B%7B%3D%3D%2Baa%2B2fz

Aquí la tabla de equivalencias.

No probe el problema con Drupal7, pero no creo que esto pase dado que el string de conexión ya no se setea mas como una url sino como un array de varias entradas.

Share

No se ejecuta Hook_Install

Supongan que estan desarrollando un módulo para drupal, lo habilitan, después de hacer unos cambios se dan cuenta que necesitan implementar un schema para el módulo y entonces implementan el hook_install. Seguramente una vez que terminaron de definir el schema van a intentar deshabilitar y volver a habilitarlo para que ejecute el hook_install e instale el schema; se llevarán la sorpresa de que no será ejecutado. Esto es así dado que este hook solo se ejecuta la primera vez que se habilita e módulo.

En algunos las encontrarán que si deshabilitan el módulo y luego lo desinstalan (uninstall) al volver a rehabilitar el modulo puede ser que ejecute el hook, lamentablemente algunos módulos no proveen soporte para uninstall.

La solución efectiva y sucia, ir hasta la tabla de system y buscar el registro que tiene como name el nombre de su módulo, si ya deshabilitaron el módulo pueden borrar esta entrada y borrar las caches, luego al habilitar nuevamente el módulo el hook_install será ejecutado.

Share