lunes, 7 de julio de 2014

[Parte 5] PHP

Manejo de errores y depuración

Hay tres tipos de fallos generales en programacion, los cuales son los siguientes:

* Errores sintacticos
* Errores en tiempo de ejecucion
* Errores logicos

En php uno de los errores mas comunes y faciles de arreglar es el punto y coma (;), que muchas veces se olvida de colocar.

Si alguna ves ejecutas el codigo y sale la pagina en blanco esto puede deberse a que no tienes habilitado (on) display_errors en php.ini.

Un error de sintaxis que ocurre mucho es cuando arroja un mensaje como "unexpected $end" este error es muy comun y pasa cuando hace falta cerrar una llave ({})  o cuando estas utilizando etiquetas en formato abreviado (<??>) y en la configuracion esta desactivada, es por eso muy recomendable utilizar <?php ?> como inicio y cierre de php, otra forma de solucionar este error es que no haya ningun espacio al final del archivo.

Otro error de sintaxis muy comun en el uso de funciones es "expects at least # parameters" donde # es el numero de parametros que se esperan en esa funcion, con esperar ese numero de parametros se refiere a eso que tienes mas o menos parametros dependiendo de como te lo indique el error, la manera mas facil de corregir este error es ir a la documentacion de php y ver como esta la sintaxis de esa funcion, documentacion php: php.net

Lo mas recomendable a la hora de estar programando es utilizar un IDE (Entorno de desarrollo integrado) de esta manera nos podemos dar cuenta de manera mas rapido de los errores que tenemos. El que yo utilizo es Sublime Text. Pero hay otros, uno de los mas usados e importantes es Dreamweaver.

Si pasa que alguna vez te sucede algun error por que pasas algun script a otro servidor puede ser que la configuracion del mismo no sea la que tenias antes por lo cual no acepte algunas de las funciones que tienes, es por eso que tenemos siempre que nos suceda eso verificar la version de PHP y MySQL y las librerias que incluye, para ello creamos un archivo php con la funcion phpinfo().

Si no sabes donde se encuentra el archivo de configuracion de PHP puedes vericarlo simplemente en el archivo creado con la funcion phpinfo() la cual muestra informacion sobre el servidor y su configuracion, pero de otra forma tambien podemos utilizar la funcion ini_set() que establece una directiva de configuracion, de manera que si utilizaramos:

 <?php ini_set('display_errors',1);?>

Nuestra directiva display_errors estaria activada.

Tambien hay una manera de eliminar los errores utilizando @ delante de una funcion no mostraria nuestro error, un ejemplo podria ser @include('archivo_que_no_existe.php'); no nos mostraria error.

Siempre que un error es mostrado, se muestra al inicio el nivel de error que es, por ejemplo: Warning: Division by zero...
en el nivel de error nos referimos a Warning, existen varios niveles veamos cuales son y que es lo que indican:



Con la funcion error_reporting() podemos seleccionar que tipo de error mostrar en tiempo de ejecucion. Unos ejemplos serian:


 <?php error_reporting(0); // Desactiva toda notificacion de error ?>


 <?php error_reporting(E_ALL ^ E_NOTICE ); // Notificar todos los errores excepto E_NOTICE ?>
 
 <?php error_reporting(E_ERROR | E_WARNING | E_PARSE); // Notificar solamente errores de ejecucion ?>



La funcion trigger_error() lo que hace es generar un error en el script PHP. El primer argumento es el mensaje de error, el segundo es opcional, y es el numero del tipo de error (el cual esta descrito en la imagen anterior). Por defecto el tipo de error utilizado es E_USER. Un ejemplo del uso de la funcion trigger_error() podria ser el siguiente:


 <?php
 if(/* alguna condicion */){
  trigger_error("Algo ha fallado!");
 }?>

Hay una mejor manera de gestionar nuestros errores utilizando la funcion set_error_handler() de manera que creamos una funcion la cual maneja los errores y los muestra personalizados, haciendolos mas entendibles para nosotros mismos. Un ejemplo simple seria el siguiente:


 <?php
 function reportar_errores(argumentos){
  //hacer algo aqui
 }
 set_error_handler('reportar_errores');?>

Al definir nuestra funcion acepta los siguientes argumentos:


 <?php
 function reportar_errores($num,$msg,$archivo,$linea,$vars){
  //hacer algo aqui
 }?>


Veamos un ejemplo completo de como podemos usar nuestra propia funcion para reportar errores:


 <?php
 // el mensaje para ver si el sitio esta subido o no
 define('ONLINE', FALSE);
 //creamos la funcion
 function reportar_errores($num,$msg,$archivo,$linea,$vars){
  // el mensaje de error
  $mensaje = "Un error a ocurrido en el script '$archivo' en la linea $linea: $msg\n";
  // le agregamos las variables que existen en el error al mensaje
  $mensaje .= print_r($vars,1);

  if(!ONLINE){ // para version en desarrollo
   echo '<pre>' . $mensaje . "\n";
   debug_print_backtrace(); // devuelve informacion sobre funciones llamadas, archivos incluidos, etc.
   echo '</pre><br />';
  }else{
   echo '<div class="error">Ha ocurrido un error en el sistema. Disculpenos por el inconveniente.</div><br />';
  }
 }

 // uso mi manejador de errores
 set_error_handler('reportar_errores');

 // creo unos errores:
 foreach($var as $v){}
 $result = 1/0;
?>


Como puedes ver en la imagen es el resultado de nuestra funcion y en la creacion de la funcion se explica todo claramente con comentarios, lo unico que tendriamos que modificar en caso de que subamos este script a un alojamiento gratuito o de paga es la constante ONLINE  en TRUE de manera que nos arrojaria un error personalizado.


Con error_log() podriamos enviar nuestro mensaje de error al registro de errores del servidor o de un fichero o simplemente a un email, de manera que si estamos ONLINE podriamos hacer que se nos enviara un error, ademas de nuestro mensaje personalizado.

La sintaxis es la siguiente:

error_log(mensaje,tipo,destino,cabeceras extras);

* mensaje es el mensaje de error que vas a enviar
* tipo es a donde va ir el mensaje: 
- 0 va para el registro del sistema, usando el mecanismo de registro del sistema operativo. Esta es la opcion predeterminada.
- 1 el mensaje es enviado por correo a la direccion que se indique en destino, es el unico tipo de mensaje donde se utiliza el cuarto parametro cabeceras extras.
- 3 es añadido al final del fichero destino. No se añade automaticamente una linea al final de la cadena mensaje.
- 4 es enviado directo al gestor de registro SAPI.
* destino su significado depende de el tipo como se indico arriba.
* cabeceras extras se usa cuando el tipo de mensaje esta establecido en 1, este tipo utiliza la misma funcion interna mail().

Errores comunes en PHP

Pagina en blanco: Posible problema en el HTML, o display_errors o error_reporting() estan desactivados.

Parse error: Se olvido colocar punto y coma (;), las llaves no estan correctamente colocadas ( inicio y cierre de llaves {}), o parentesis, o comillas, o las comillas no han sido escapadas.

Empty variable value: Se olvido colocar el caracter inicial de una variable signo de dolar ($), la variable esta mal escrita o no esta respetando que es case-sensitive, o uso inapropiado de la variable con respecto a su ambito (esto sucede mucho en funciones).

Undefined variable: Se esta haciendo referencia a la variable antes de ser creada o simplemente no tienen ningun valor y esta vacia para ello podemos checar Empty variable value

Call to undefined function: Nombre de la funcion esta mal escrito, PHP no esta configurado para utilizar esa funcion (esto se puede deber a alguna libreria que no contiene), contiene una funcion que no ha sido incluida (a esto me refiero que no ha hecho include a algun archivo donde se encuentra la funcion en si).

Cannot redeclare function: Existen dos declaraciones en la misma funcion, esto puede deberse al incluir algun archivo, entonces lo recomendable es mirar si no incluistes dos veces el mismo archivo.

Headers already send: Existe un espacio en el script antes de las etiquetas de PHP, los datos que ya se han mostrado o se ha incluido el archivo dos veces.

Al momento de querer reparar algunos errores es buena idea utilizar comentarios, comentamos alguna linea para ver que es lo que esta pasando y si es la linea que esta causando ese error o simplemente no podemos usarla por el momento por que el servidor no esta configurado correctamente para utilizar esa funcion (por ejemplo la funcion mail()).

Tambien podemos mostrar lo que contiene alguna variable o array de manera que veamos en que estamos equivocandonos,  para ello podemos usar las funciones echo o print en caso de variables o print_r o var_dump en caso de arrays.

echo $variable_contiene_algo_importante;
print_r($array_contiene_algo_importante);
A que contiene algo importante me refiero a que es algo importante para que el script siga su ejecucion, pero como en realidad las variables o arrays no lo estamos viendo entonces los mostramos para saber si algun valor se esta pasando correctamente o hay algun error.

Muchas veces una condicional o un bucle son los que pueden estar causando nuestro error en caso de querer comentarlos podemos utilizar el comentario multilinea /* acadentrolacondicionalobucle */.

Muchos utilizan la funcion die() o exit() para terminar el script en caso de que un error suceda, mostrando un mensaje del error... por ejemplo:


<?php
 $nombre_archivo = 'ruta/hacia/archivo-datos';
 @fopen($nombre_archivo,'r') or exit("No se pudo abrir el archivo ($nombre_archivo)");
?>


Como vemos en este caso utilizamos el @ para suprimir el error de fopen y con la funcion exit() mostramos el mensaje de error personalizado, podriamos haber usado die() en lugar de exit() y seria lo mismo.

Muchas veces también tenemos algunos errores en MySQL (en nuestras consultas) en estos casos lo mejor seria mostrar nuestra variable de consulta $query, de manera que podamos ver como es que se están pasando los valores y en que es lo que nos estamos equivocando... o simplemente ejecutar la consulta desde phpmyadmin o desde consola. Muchas veces suele suceder al no poner el tipo de dato correctamente tal como una cadena por ejemplo. O también hacer uso de print_r() en caso de mostrar un array para ver donde se encuentra el valor que necesitamos.

Un error muy común es cuando nos arroja un mensaje como "Access denied for user: user@localhost" esto sucede ya que algún parámetro a la coneccion puede estar mal colocado o simplemente el usuario a sido baneado por realizar demasiadas consultas (sobrecargando el servidor).

Bueno hasta aquí les dejo la parte 5 de PHP, puede que les parezca algo mal redactado y puede ser que así sea, solo que esta semana no he tenido bastante tiempo como para darle un buen formato y no los quería dejar sin seguir los tutoriales es por eso que lo hice de esta manera, espero que les guste y que puedan encontrar errores en su código de manera mas rápida, saludos.

No hay comentarios:

Publicar un comentario en la entrada