Depurar en PHP: Eclipse PDT + Xdebug
Introdución
Como continuación del tutorial Desarrollos
Web en PHP con AppServ 2.5.6 y Eclipse PDT introducimos en este la capacidad de depurar desde el propio
Eclipse PDT con la extensión para PHP Xdebug.
Recordemos el entorno utilizado:
- Windows 32 bit (2000, XP, Vista)
- Java 5 o posterior
- Appserv 2.5.6
- Eclipse PDT 3.3 (aka Europa)
Xdebug – Debugger and Profiler Tool for PHP
Xdebug es una
extensión para PHP, distribuida bajo The PHP License 3, que proporciona un soporte muy completo para la depuración de
nuestros scripts. Enumerando sus características principales:
- Añade características avanzadas en el volcado del valor de las variables, al sobreescribir la
función de PHP var_dump(). - Las trazas de error incluyen información personalizable, y son lanzadas automáticamente cuando
PHP genera un mensaje a nivel de warning, error o info. - Permite hacer trazas personalizables de funciones: invocaciones, valor y tipos de parámetros y
valores de retorno. - Incluye un analizador de cobertura de código. No sólo es útil para posibles detecciones
de código inaccesible sino también para conocer el alcance de nuestros test unitarios. - Hacer análisis de rendimiento. Detectar cuellos de botella, tiempos muertos, carga de recursos y
en general, el comportamiento de nuestros script PHP con la información manejada en tiempo de
ejecución. La información generada por el profiles puede ser posteriormente analizada visualmente
con las aplicaciones opensource y GPL KCacheGrind (linux+KDE), o WinCacheGrind (Windows). - Añade la posibilidad de depuración a cualquier cliente que sea capaz de ejecutar scripts PHP y
soporte el protocolo DBGp. Esto es, ofrece características de
depuración remota para Eclipse PDT, NetBeans, Notepad++, Protoeditor, Komodo… ¡e incluso
vim!! - Xdebug incluye un cliente de depuración standalone y opensource: Xdebugclient 0.9.0
En nuestro caso nos intesesa el punto 6, la depuración remota con Eclipse PDT.
Instalar Xdebug en PHP 5 versión AppServ
2.5.6
El proceso es simple:
- Descargar la librería .dll desde Xdebug para nuestra versión apropiada de PHP. En mi caso,
php_xdebug-2.0.3-5.1.7.dll - Copiar la librería en el directorio ext de la instalación de PHP (e.g. C:\AppServ\php5\ext\)
- Añadir a php.ini (e.g. C:\Windows\php.ini):
zend_extension_ts="C:\AppServ\php5\ext\php_xdebug-2.0.3-5.1.7.dll" xdebug.remote_enable=On xdebug.remote_host="localhost" xdebug.remote_port=9000 xdebug.remote_handler="dbgp"
- Reiniciar AppServ (o PHP)
Configurar Eclipse PDT con Xdebug
Partiendo de la configuración de Eclipse del tutorial Desarrollos
Web en PHP con AppServ 2.5.6 y Eclipse PDT, realizamos las siguiente modificaciones desde el menú
Window | Preferences:
- PHP | PHP Executables, editamos el nombre del ejecutable existente e introducimos los datos:
- PHP | Debug, y establecemos en Default Settings XDebug como PHP Debugger:
- Establecer el navegador externo a Eclipse PDT. No es obligatorio pero sí recomendable. General | Web
Browser: - Reiniciar Eclipse
Ejemplo: depuración PHP propagada
utilizando breakpoints
Voy a poner como ejemplo el código PHP enviado por un lector. Le dedico este tutorial, y espero que le sirva para resolver la duda que me planteaba.
Se trata de dos páginas PHP con un formulario que almacena en la base de datos MySQL un nombre, ciudad y
provincia. Creamos un proyecto PHP con directorio del mismo en, por ejemplo, C:\AppServ\www\debug_test y las
incluimos:
Eclipse PDT PHP Explorer
El código es:
pagina1.php
<html> <head> <title>pagina1.php</title> </head> <body> <form method="post" action="pagina2.php"> <table width="70%" border="0" align="left"> <?php // Me conecto a la base de datos mysql_connect("localhost","test","test"); mysql_select_db("combobox"); // Declaro la variable $paisant que es la que me va a indicar // si hay que volver a cargar los datos de las provincias $paisant=$pais; print (" <tr> <td><div align=\"right\"><strong>Nombre y Apellido:</strong></div></td> <td> <input type=\"text\" name=\"nombre\" value=\"$nombre\"></td> </tr> <input type=\"hidden\" name=\"paisant\" value=\"$paisant\"> <tr> <td><div align=\"right\"><strong>Pais:</strong></div></td> <td><select name=\"pais\" onchange=\"submit();\"> "); //Muestra el combobox de las provincias una vez que se haya elegido el pa , no antes if (!isset($pais)){ print ("<option selected>Seleccione el pais</option>"); $pais="0"; } $sql="select * from pais order by 2"; $res=mysql_query($sql); while($fila=mysql_fetch_array($res)){ print("<option value=\"$fila[idp]\""); if ($fila[idp] == $pais) { print ("selected"); } print(">$fila[pais_new]</option>\n"); } print("</select></td></tr>"); if ($pais!="0"){ print(" <tr> <td><div align=\"right\"><strong>Provincia:</strong></div></td> <td><select name=\"prov\"> "); $sqlprov="select * from dep where pais_idp='$pais' order by 2"; $resprov=mysql_query($sqlprov); while($filaprov=mysql_fetch_array($resprov)){ print("<option value=\"$filaprov[departamento]\">$filaprov[departamento]</option>"); } print(" </select> </td> </tr> "); } ?> <tr> <td><div align="right"><input name="button" type="submit" value="Enviar"></div></td> <td><input name="reset" type="reset" value="Borrar"></td> </tr> </table> </form> </body> </html>
pagina2.php
<?php if ($paisant!=$pais) { header("location:pagina1.php?nombre=$nombre&pais=$pais"); } else { echo "Ingreso de datos a la base de datos"; } ?>
y el script para configurar la base de datos, bajo un esquema combobox y un usuario test y password test con permisos a ese esquema:
-- -- Estructura de tabla para la tabla `dep` -- CREATE TABLE `dep` ( `iddep` int(10) unsigned NOT NULL auto_increment, `pais_idp` int(10) unsigned NOT NULL, `departamento` varchar(25) default NULL, PRIMARY KEY (`iddep`), KEY `dep_FKIndex1` (`pais_idp`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ; -- -- Volcar la base de datos para la tabla `dep` -- INSERT INTO `dep` VALUES (1, 1, 'Puno'); INSERT INTO `dep` VALUES (2, 1, 'arequipa'); INSERT INTO `dep` VALUES (3, 2, 'cordoba'); INSERT INTO `dep` VALUES (4, 2, 'San Luis'); -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `distrito` -- CREATE TABLE `distrito` ( `dep_iddep` int(10) unsigned NOT NULL, `distrito_new` varchar(12) NOT NULL, KEY `distrito_FKIndex1` (`dep_iddep`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -- -- Volcar la base de datos para la tabla `distrito` -- INSERT INTO `distrito` VALUES (1, 'Juliaca'); INSERT INTO `distrito` VALUES (1, 'Puno'); INSERT INTO `distrito` VALUES (1, 'huancane'); INSERT INTO `distrito` VALUES (1, 'azangaro'); INSERT INTO `distrito` VALUES (3, 'santo tome'); INSERT INTO `distrito` VALUES (3, 'santiago'); INSERT INTO `distrito` VALUES (3, 'Chaco'); INSERT INTO `distrito` VALUES (3, 'San Rafael'); -- -------------------------------------------------------- -- -- Estructura de tabla para la tabla `pais` -- CREATE TABLE `pais` ( `idp` int(10) unsigned NOT NULL auto_increment, `pais_new` varchar(25) default NULL, PRIMARY KEY (`idp`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ; -- -- Volcar la base de datos para la tabla `pais` -- INSERT INTO `pais` VALUES (1, 'peru'); INSERT INTO `pais` VALUES (2, 'argentina');
Con el foco sobre el proyecto debug_test, ejecutamos en Eclipse Run | Open Debug Dialog… | doble click sobre
PHP Web Page y lo configuramos:
Eclipse PDT Configuration Launch con XDebug para el proyecto debug_test
Pulsamos en Apply. Si queremos probar si la aplicación funciona correctamente, podemos pulsar en Run:
Formulario PHP utilizando MySQL
En pagina1.php y pagina2.php ponemos algunos puntos de ruptura de manera habitual en Eclipse. Cambiamos a la
perspectiva de PHP Debug e iniciamos la depuración que hemos configurado anteriormente. Se
iniciará un navegador en windows y quedará a la espera de que en Eclipse avancemos por el
código paso a paso, por breakpoints, etc, mostrándose en la ventana Variables el valor de las
variables (podemos modificar su valor al vuelo y ver cómo afecta) y en la parte inferior, el código
donde se resalta la línea actualmente en depuración:
Depurando el script PHP con Xdebug en Eclipse PDT
A medida que avancemos entre las páginas y enviemos los datos del formulario podemos consultar sus valores
en el GET o POST de la request, valores almacenados en la sesión, etc., de manera habitual en Eclipse
desde la perspectiva de depuración:
Informacion de depuracion con Xdebug en Eclipse PDT
Hemos llegado al final de la secuencia de pantallas de nuestro programa:
Depuracion completada a lo largo de toda la secuencia en PHP
Finalmente indicar que Xdebug es muy versátil puede personalizarse con las opciones que describen en su
documentación.
Conclusión
Como hemos visto, el uso de Eclipse para desarrollar en PHP no sólo uniformiza el entorno de
programación sino también de depuración. La depuración remota es habitual en muchos
servidores en java (por ejemplo). La distribución de PHP no ofrece esa característica per se, pero
acabamos de ver cómo existen complementos de libre distrubución que ofrecen un soporte perfecto
para nuestras necesidades.
PD: para propósitos empresariales con PHP quizás te interese Zend y Zend Debugger como
soluciones más potentes.
Me sirvio de mucho, estoy urgando con ORACLE y esto me sirve de mucho. nunca habia podido configurar el debug en eclipse. gracias.
Hola antes que nada muchas gracias por el tutorial. Solo queria comentarte que tuve problemas para correr la aplicación, me manda los siguientes errores:
Notice: Undefined variable: pais in C:\\\\wamp\\\\www\\\\debug_test\\\\pagina1.php on line 20
Notice: Undefined variable: nombre in C:\\\\wamp\\\\www\\\\debug_test\\\\pagina1.php on line 28
Y lo unico que hice fue copiar y pegar el codigo que esta aqui en la página y al ejecutarlo me manda estos errores. La base de datos si la pude crear correctamente y sin ningun problema junto con sus tablas.
Espero me puedas ayudar a resolverlo.