Es muy difícil desarrollar paginas en PHP y no encontrarse nunca con un error o que no funcione como queremos. Aquí comento unas cuantas ideas que me facilitan la tarea de encontrar y solucionar los errores de mis paginas.
En todo momento hay que conocer la versión y configuración de PHP, así como del servidor Web que usemos y del motor de Base de Datos si corresponde. La forma más sencilla de tener siempre presente la configuración de PHP es tener impresa la ultima versión de la pagina generada por la función phpinfo(). Muchas funciones dependen de los valores que aquí aparecen.
Otro punto a tener en cuenta es el editor de código que se use. Aunque se puede escribir paginas PHP ( y HTML ) en el bloc de notas de Windows, es mejor utilizar editores de código que por lo menos cuente con numeración de líneas y de resalto de sintaxis. La numeración de líneas es muy útil ya que en los mensajes de error de PHP normalmente nos indica el numero de línea donde ocurrió el error. Y el resalto de sintaxis nos facilita la localización de ciertos errores de escritura. También es recomendable que el editor tenga la opción de integrar la ayuda de PHP, para poder acceder a ella dentro del contexto del editor.
Siempre debe estar a mano. En él esta todas las referencias del lenguaje. Si tienes una conexión permanente a Internet, lo mejor es acceder a la versión on-line de http://www.php.net . Y si es posible, la versión en Ingles comentada por los usuarios. Es la mas actualizada, y muchas veces encontraremos la solución a nuestros problemas en los comentarios de los usuarios.
También es recomendable tener el manual integrado con el editor de código. Esto nos permite acceder a la definición de una función PHP dentro del entorno de desarrollo.
Siempre que nos dé un error una función y no encontramos a primera vista la causa, es conveniente ver en el manual la definición de esa función. Quizás en la explicación de la función o de sus parámetros encontremos la respuesta. O un usuario haya tenido el mismo problema y haya dejado su solución entre los comentarios.
Además viene en que versión de PHP funciona y que directivas del php.ini afectan su ejecución.
Suele ser una buena idea ojearlo, ya que en sus capítulos temáticos y apéndices viene mucha información útil.
Siempre hay que leerlos y entenderlos. Muchas veces ese mensaje nos explica la causa y la forma de solucionarlo. Y nos dice en que línea de código PHP detecto el error. Y digo detecto porque la causa del error puede estar en esa línea, en las líneas anteriores, en otro fichero ( que hayamos incluido) o incluso en la configuración de PHP. Y en el peor de los casos, ese mensaje nos sirve para que la ayuda que recibamos en los foros sea más exacta, porque el mensaje de error y el código que lo produce complementa la descripción del problema.
Para que nos aparezcan los mensajes de error, la directiva del php.ini display_errors debe estar a On. Como todo buen lenguaje, existen varios niveles de error: notas (E_NOTICE), errores de parse (E_PARSE), avisos (E_WARNING) y errores (E_ERROR). Se puede configurar PHP para que solo muestre los mensajes de alguno de estos niveles con la directiva error_reporting o con la función error_reporting(). La configuración "normal" es mostrar todos los mensajes menos las notas, aunque yo recomendaría mostrar todos, al menos en las primeras fases de desarrollo.
La razón por la que normalmente se desactivan las notas es porque a veces provocamos ese error porque nos aprovechamos de características de PHP. El ejemplo mas claro es cuando tenemos un formulario y queremos que en sus campos aparezcan los valores que metimos al rellenarlo y enviarlo. El código seria:
<input type="text" name="texto_1"
value="<?php echo $_POST['texto_1']; ?>">
Es un código muy usado. Pero que provoca un mensaje de error la primera vez que se muestra el formulario.
Warning: Undefined index: texto_1 in C:\WINDOWS\TEMP\~scp.php on line 7Porque PHP detecta que se esta intentado acceder al valor de una variable que no "existe". Funciona porque PHP inicializa automáticamente a NULL las variables la primera vez que se accede. Por eso en este caso tener activados los mensajes de las notas nos "estorba".
Pero consideremos el siguiente código:
<?php
$variable_1="valor";
//....
$consulta="insert into tabla (id,campo1,campo2,campo3,campo4) values ($id,".$array[$i*$j].",'$varable_1','casa','Esto es ".$var."')";
?>
Como se ve he cometido un fallo de "escritura" (el que tiene dedos se equivoca) al escribir $variable_1 dentro de la consulta. Si tengo desactivado los mensajes de las notas, PHP no nos avisara del error y siempre estaremos insertando NULL en el campo2. Sin embargo, con ellos activados, PHP nos avisara diciendo que se esta intentando acceder a la variable $varable_1 que no esta definida. Y es este tipo de error los que nos hacen perder un montón de tiempo intentando localizarlo.
Warning: Undefined variable: varable_1 in C:\WINDOWS\TEMP\~scp.php on line 14Por eso mi recomendación de mostrar todos los mensajes en las primeras fases de desarrollo.
TRUCO: Si estamos seguros de que no nos hemos equivocado de variable, podemos ocultar este error con el uso de @. Este operador evita que se muestre el mensaje de error de la linea donde se coloca. El codigo quedaría:
<input type="text" name="texto_1" value="<?php echo @$_POST['texto_1']; ?>">
Además, con esto conseguimos que el script se ejecute igual independientemente del nivel de error que este configurado PHP.
OJO: solo se debe tener activa la visualización de los mensajes de error durante la fase de desarrollo de la pagina. En los entornos de producción es recomendable tener la directiva display_errors a Off. La razón: esos mensajes que nos dan tanta información a la hora de depurar y corregir errores, también dan mucha información sobre la forma en que trabaja nuestra pagina. Y esa información puede facilitar mucho la tarea de hackers y otros especimenes.
Muchas funciones devuelven un valor. Pero otras devuelven un valor valido cuando se ejecutan correctamente y otro valor no valido cuando se produce un error, a veces sin mostrar mensaje de error. Si no comprobamos que se ha devuelto el valor valido y usamos el valor devuelto directamente, nos arriesgamos a usar el valor no valido que posiblemente provoque un error. Uno de los casos más comunes es el de la función mysql_query(). Si se ejecuta correctamente la consulta devuelve un "recurso de resultado de MySQL" y en caso de fallar la consulta FALSE y no muestra mensaje de error. Si luego intentamos usar el valor devuelto en otra función (p.ej. mysql_fetch_array()) y ha devuelto FALSE, PHP nos dará un error en mysql_fetch_array(). Habría que comprobar si mysql_query() ha devuelto un valor valido y si no, mostrar el error de MySQL. Por ejemplo:
<?php
$result=mysql_query($consulta);
if (!$result) {
echo "Error MySQL: ".mysql_error();
exit;
}
?>
Esto nos mostrara el error de la consulta y parara la ejecución del script. Suele ser recomendable comprobar el valor devuelto por una función siempre que este valor pueda indicar si se ha producido un error en la ejecución de la función, aunque este valor no se utilice mas adelante (como en los mysql_query() con una consulta de inserción o actualización).
En la definición de la función en el manual viene especificado el valor que devuelve, así como si devuelve un valor especial en caso de error.
OJO: como indique antes, no es conveniente mostrar mensajes de error que muestren el funcionamiento interno de nuestra pagina en entornos de producción, así que seria aconsejable sustituir el mysql_error() por un texto menos significativo.
Si lo que mostramos es el valor de una variable, o el resultado de una función a la que hemos pasado una variable, hay que revisar donde se ha asignado el valor a esa variable. Para comprobar los valores es recomendable hacer un echo antes de su uso para ver su valor durante la ejecución del script.
Esta suele ser una situación incomoda, ya que no sabemos por donde empezar. Yo recomiendo un método sencillo y mecánico. Consiste en generar una traza de la ejecución del script. Esta traza consiste en realizar una serie de echo que indiquen las acciones realizadas por el script. Comenzaría por mostrar los valores variables, mostrar cuando cambian el valor de las variables, mostrar el valor de las variables antes de un if, mostrar que esta dentro de un bucle, mostrar la cadena que paso como consulta a la base de datos, etc. Si el script es muy grande, se realiza por trozos de código. Una vez comprobado que el código de un trozo funciona correctamente y genera los valores esperados, se quitan los echo y se pasa al siguiente trozo de código.
Para facilitar esta traza es recomendable pasar el menor numero de cadenas directamente como parámetros. En su lugar usar variables. Por ejemplo:
<?php
mysql_query("update tabla set campo1=$id"); // difícil mostrar la
consulta
$consulta="update tabla set campo1=$id"; // ahora es tan sencillo
como hacer echo $consulta
if (!mysql_query($consulta)) {
echo "Error en la consulta: $consulta <br>";
echo "MySQL
dice: ".mysql_error();
exit;
}
?>
Puede parecer una tontería, pero es mejor tenerlo en cuenta. Si tu script te ha dado varios mensajes de error, céntrate en corregir el primero. Hay muchas posibilidades que corrigiendo ese el resto se solucionen.
Hay ciertos errores que son producidos por un pequeño despiste al teclear o al no tener muy claro como funciona alguna parte de PHP. Por ejemplo, si usamos = dentro de una condición, PHP asignara el valor. Si queremos comparar, debemos usar == (o === si queremos que sean idénticos). Y es muy fácil que se nos olvide el segundo =. Un truco que ayuda evitar este error en el caso de comparar con un valor constante (no una variable), es colocar el valor en el lado izquierdo de la comparación. Si ponemos un solo igual, PHP dará un error. Por ejemplo:
<?php
if ("A"==$var) {
?>
Otro aspecto a tener en cuenta es el funcionamiento de OR, AND, || y &&. A parte de sus diferencias en el orden de precedencias (ver en el manual), hay que tener en cuenta que actúan en "cortocircuito", es decir, solo se evalúan las condiciones necesarias para saber su valor. En el caso de OR y ||, se evalúan todas las condiciones hasta encontrar una que sea verdadera; en el caso de AND y &&, hasta encontrar una falsa. Por ejemplo:
<?php
funcion1() || funcion2()
?>
Solo se ejecutara funcion2() si funcion1() devuelve falso.
Otra cosa a controlar son las condiciones de los bucles, ya que a veces las ponemos de forma que hagan una iteración de mas o de menos. O colocamos por inercia un ; al final de la sentencia de bucle (for, while, ...) y nos cargamos el bucle.
Teniendo en cuenta estos consejos, seremos capaces de localizar nuestros propios errores e intentar corregirlos. Y si no conseguimos corregirlos, dispondremos de mucha información para documentar nuestro problema en los foros.
@Copyright 2003 Jose Miguel Martínez. Todos los derechos reservados.
Si quieres comentarme algo sobre el articulo, tienes alguna idea de como mejorarlo o quieres correguir algo, mandame un email a josemifaq@lycos.es