Programación

Cómo realizar la depuración de código en PHP

Siguiendo el anterior post sobre Docker que hacía referencia a como mejorar los procesos internos de desarrollo,  esta vez mostraremos cuan fácil es tener un entorno de depuración equivalente al de un entorno de desarrollo de escritorio pero para páginas web.

Tradicionalmente los lenguajes de programación de escritorio como C++, C#, .Net han permitido a los programadores realizar operaciones de testeo de código línea a línea en el momento de ejecución del programa.

Estas operaciones incluían el ver el valor de las variables del programa en un momento dado, ir ejecutando paso a paso todas las instrucciones del código, hacer modificaciones al momento, etc.

En web esto siempre ha sido mucho más complicado porque habitualmente el servidor web está en una máquina y el navegador en otra.
También las peticiones http de los navegadores son per sé sin estado o stateless, lo que significa que en un momento dado dos peticiones web desde un mismo navegador no necesariamente han de saber nada una de la otra.

Este punto siempre se ha podido sobrellevar mediante el uso de cookies y variables de sesión que permitían al servidor web relacionar peticiones web de un mismo navegador para dar la impresión de conexiones con estado o stateful del inglés.

El encargado de permitir la depuración de código en desarrollo se llama Xdebug. Es una extensión para PHP que nos proporciona un soporte muy completo.

En SEOCOM utilizamos Docker para virtualizar el servicio PHP-FPM. Este proceso FastCGI permite procesar ficheros PHP teniendo como frontend Apache o Nginx.

Para crear nuestro contenedor haremos uso de la imagen PHP56 de nmcteam y nuestro Dockerfile personalizado.

FROM nmcteam/php56
MAINTAINER David Garcia
# Activamos la opcion de short tags ""
RUN sed 's@short_open_tag = Off@short_open_tag = On@g' -i /etc/php5/fpm/php.ini
RUN sed 's@short_open_tag = Off@short_open_tag = On@g' -i /etc/php5/cli/php.ini
# Eliminamos ficheros por defecto de la configuración para poder sobreescribirlos mediantes docker
RUN rm /etc/php5/mods-available/xdebug.ini
# Cambiamos a la carpeta root
WORKDIR /root

Y ahora lo importante, la configuración en desarrollo de fichero xdebug.ini

[xdebug]
zend_extension=xdebug.so
xdebug.idekey=DESARROLLO
xdebug.remote_enable=on
xdebug.remote_port=9000
xdebug.remote_connect_back=On
xdebug.remote_handler=dbgp
xdebug.profiler_enable=0
xdebug.profiler_output_dir="/temp/profiledir"

La depuración con Xdebug funciona de la siguiente manera “a grosso modo”. Cuando el servidor web recibe una petición, y la misma solicita debug (mediante cookie), el modulo php comienza el procesado del mismo.

El módulo Xdebug se conecta a la ip origen de la misma (xdebug.remote_connect_back=On) y al puerto 9000 (xdebug.remote_port=9000).

Si tiene éxito empieza a enviar información sobre los valores de las variables y demás datos de relevancia para nuestro depurador.

Sabiendo esto, solamente nos quedaría configurar nuestro IDE de programación favorito. Por ejemplo, la configuración en PhpStorm quedaría de la siguiente manera.

La sección Xdebug ha de tener el Debug port igual al especificado en el fichero xdebug.ini y ha de tener activo el check de “Can accept external connections”.

Ahora le indicaríamos al entorno que estuviera atento a las conexiones de Xdebug.

Para evitar que el servidor PHP-FPM este intentando conectarse cada vez se le ha de indicar al proceso que queremos esta depuración.

Habitualmente se realiza generando una cookie específica. Un sistema muy sencillo de conseguir generar esta cookie es mediante el uso de la extensión Chrome “Xdebug helper”.

Una vez instalada, la configuraremos para que el valor de IDE sea el mismo que tenemos configurado en el archivo de configuración de xdebug.ini “DESARROLLO”.

Y finalmente, activaremos el módulo en la url concreta gracias al icono que aparece en las webs del navegador.

Si todo es correcto, al empezar la conexión veremos que el IDE puede empezar a generar el proceso de depuración y realizar las pruebas oportunas.

Gracias a Docker, todo este proceso de configuración es automático y sencillo de ejecutar con un solo comando en el fichero docker-compose.yml si utilizamos Compose o mediante una llamada a Docker desde línea de comandos.

En un próximo post ampliaremos estas configuraciones para ver el conjunto.