Foros del Web » Programando para Internet » PHP »

Control de errores como Dios manda

Estas en el tema de Control de errores como Dios manda en el foro de PHP en Foros del Web. Hola amigos. Solicito vuestra ayuda para lo siguiente. Estoy con el control de errores despues de mysql_query. Efectivamente, hay un monton de informacion por la ...
  #1 (permalink)  
Antiguo 06/09/2011, 05:26
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Control de errores como Dios manda

Hola amigos. Solicito vuestra ayuda para lo siguiente.

Estoy con el control de errores despues de mysql_query. Efectivamente, hay un monton de informacion por la red, pero, como casi siempre, hay tanta, que al final te lias (es mi opinion).

La cosa es que, cada vez que hago un mysql_query, quiero usar las funciones mysql_errno y mysql_error para capturar el numero y el texto del mensaje. Para ello, veo que mucha gente usa or die para mostrar el mensaje.

El problema es que, cada vez que lo hago, funciona, pero el mensaje me lo muestra, normalmente en el siguiente sitio de pruducirse el mensaje, ya sea un div, una tabla, lo que haya y ademas, como die funciona como exit, deja de mostrar todo lo demas, por lo que el impacto visual es un poco desastroso.

Había pensado que, si se produce el error, enviar al usuario a otra pagina y allí capturar el error, pero veo que cuando rediriges a otra pagina con Header, las funciones de error ya no funcionan.

Tambien había pensado capturar los mensajes y reenviarlos por la url, pero, como ya sabeis, puede dar problemas el enviar mensajes por url tan grandres, a parte que no me gusta.

Bueno, la cosa es ver si me podeis ayudar a solucionar esto, es decir, a ver que idea podeis tener para poder capturar los errores con las funciones mencionadas y mostrarlos de una forma un poco decente.

Espero vuestra ayuda. Muchas Gracias. Un saludo.
  #2 (permalink)  
Antiguo 06/09/2011, 05:35
Avatar de pateketrueke
Modernizr
 
Fecha de Ingreso: abril-2008
Ubicación: Mexihco-Tenochtitlan
Mensajes: 26.399
Antigüedad: 16 años
Puntos: 2534
Respuesta: Control de errores como Dios manda

Los errores solo se deberían suscitar en entornos de desarrollo, cuando finalmente pasas a producción dichos errores no deben ser mostrados.

De ahí que se recomienda tener una vista personalizada como mencionas, pero solo en entornos de producción, imagina esto:
Código PHP:
mysql_query($sql) or mi_error($sql); 
Dicha función debe reaccionar como te menciono, solo es cuestión de ingeniarla.
__________________
Y U NO RTFM? щ(ºдºщ)

No atiendo por MP nada que no sea personal.
  #3 (permalink)  
Antiguo 06/09/2011, 05:55
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

Hola. Gracias por respuesta.

Mira, había pensado esto, a ver que te parece. Todavia no tengo el codigo porque estoy en ello ahora mismo, pero pongo la idea como sería, ya que el codigo creo que es bastante facil.

- Despues de cada mysql_query, llamamos una funcion que se llame por ejemplo control_errores

- La funcion control_errores crea variables de session con las funciones de errores (las mencionadas en el post anterior) y redirige a la pagina de errores.

- Creamos una pagina de errores para mostrar las variables de session.

- Ponemos un boton para volver atras o volver al inicio. Destruimos las variables de session.

Lo he probado en sucio y parece que funciona, aunque me vendría muy bien vuestra opinion y si se os ocurre algo para mejorarlo.

Un saludo.
  #4 (permalink)  
Antiguo 06/09/2011, 06:32
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Control de errores como Dios manda

Buenas,

Es interesante el post, porque estás buscando un diseño antes de ponerte a programar y eso es algo muy valorado hoy día, la gente que viene a estos foros lo hacen todo alrevés, empiezan la casa por el tejado y luego salen mil dudas.

Yo te recomiendo, ya que quieres hacer algo lo más general posible que encapsules todas las operaciones que van a la base de datos en una clase. Así, además, matas dos pájaros de un tiro: controlas los errores de una forma mucho más intuitiva y atómica y tienes una clase de acceso a la base de datos que te puede servir para otras aplicaciones.

Si te interesa el tema, te puedo guiar un poco, te puedo comentar cómo lo tengo montado yo y ya vas sacando de ahí tu idea.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #5 (permalink)  
Antiguo 06/09/2011, 07:07
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

Hola vgonga1986, te comento varias cosas.

En primer lugar, darte las gracias por entrar en el post, te lo agradezco.

Hablando de ello, ya he terminado el codigo tal y como expliqué en el post anterior, para quien le pueda servir, no pongo el codigo ya que creo que es bastante sencillo, además, hay muchas pistas en lo ya comentado.

Por otro lado, agradecerte tu comentario por el tema del diseño. La verdad, es que, cuando te das cuenta, es mucho mejor trabajar de esa forma, aunque pareca mas lenta, es mucho mas rapida, ordenada y además, creo que se aprende mucho mas.

Por ultimo, con respecto a la solución que me diste, me ha venido muy bien y te voy a decir porqué.

Normalmente, conozco el tema de POO e incluso tengo algunos conocimientos al respecto, pero nunca he sido capaz (aunque parezca increible) de sacarle partido, ya que me forma de trabajar hasta ahora es con funciones e includes, y la verdad, me va bastante bien.

Indirectamente, en tu respuesta, me has dado una razón que llevo buscando durante mucho tiempo, ya que, efectivamente, si hay una clase donde se hagan todos los mysql_query, con modificar dicha clase e incluir el control de errores del que trata este tema, no tendría que haber estado ahora modificando todos los mysql_query que tengo, que, dicho sea de piso, como en este proyecto llevo pocos dias, pues no son muchos.

Por si no me captas la idea, saliendome del tema, me has dado una razón para cambiarme a POO y aprovechar sus ventajas, que, repito, aunque no te lo creas, no las veía. Algo sospechaba ya que los buenos programadores, normalmente, usan POO, pero no era capaz de verlo.

Bueno, que no me enrrollo mas, gracias por todo. Un saludo.
  #6 (permalink)  
Antiguo 06/09/2011, 07:10
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

Por cierto, si lo crees conveniente, si me puedes dar alguna pista sobre como hacer, tambien me iría muy bien.
  #7 (permalink)  
Antiguo 06/09/2011, 07:55
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: Control de errores como Dios manda

Que tal AitorLopez,

Te sugiero que le des una mirada a PDO y aproveches(dentro de las tantas ventajas que tiene) el manejo de excepciones.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #8 (permalink)  
Antiguo 06/09/2011, 08:40
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Control de errores como Dios manda

Te lanzo una pequeña idea de lo que creo que tiene que tener toda clase de acceso a bases de datos (control de errores incluido). Esto se puede aplicar a los errores normales de los query o a excepciones, como bien ha indicado @masterpuppet.

La idea es sencilla, encapsular toda operación, de forma que desde fuera de la clase sólo haya que llamar a una función cada vez (simulando que son operaciones atómicas). Yo lo tengo más o menos así:
- Atributos de la clase: host, user, password, database, connection y message.
- Constructor: que asigne host, user, password y database.
- Funciones de Connect y Disconnect: en la primera tendrás que hacer mysql_connect y mysql_select_db, de forma que crees ya la conexión.
- Funciones de ejecución de sentencias: normalmente una para cada tipo de operación, aunque luego el código es casi idéntico, pero así lo modularizas más: Update, Insert, Delete y Select. La diferencia es que la última tendrá que devolver el ResultSet, para que luego puedas hacer fetch y recorrer los resultados (esto también lo puedes hacer en la clase, pero yo lo veo innecesario).
- Funciones de control de errores: tienes un atributo llamado $message. Pues creas unas cuantas funciones para acceder, modificar e imprimir dicho mensaje: SetMessage, GetMessage, PrintMessage y ConcatMessage (por ejemplo).

Una vez la tengas montada, tienes que añadir a las funciones susceptibles de dar error el control de errores gracias a las funciones para ello. Por ejemplo:
Código PHP:
Ver original
  1. function SetMessage($message) {
  2.     $this->message = $message;
  3. }
  4. function GetMessage() {
  5.     if (empty($this->message)) {
  6.         return '';
  7.     }
  8.     return $this->message;
  9. }

Luego en Connect puedes hacer lo siguiente:
Código PHP:
Ver original
  1. if (!$this->connection = mysql_connect($this->host, $this->user, $this->pass)) {
  2.         $errno = mysql_errno($this->connection);
  3.         $error = mysql_error($this->connection);
  4.         $this->SetDBMessage('Error en el acceso a la Base de Datos. Por favor, asegúrese de que las credenciales de acceso son correctas. Error MySQL (' . $errno . '): ' . $error);
  5.     }

De esta forma te queda todo bastante ordenado, incluso, si te animas puedes construir un fichero de log. Es simplemente añadir el acceso al log y la escritura cuando llames a SetMessage, puedes ir añadiendo una línea por cada operación.

Este método tiene una ventaja más, puedes utilizar las funciones que afectan al mensaje no sólo como control de errores, sino también para aciertos. Por ejemplo, en el Select puedes poner un mensaje en $message:
Código PHP:
Ver original
  1. $this->SetDBMessage('La consulta ha sido ejecutada de forma satisfactoria. Se han obtenido ' . mysql_num_rows($rs) . ' resultados.');

Bueno, sólo son unas pequeñas anotaciones, pero si decides montarlo así, me puedes preguntar siempre que tengas alguna duda.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #9 (permalink)  
Antiguo 06/09/2011, 10:40
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

Hola.

Gracias de nuevo por las respuestas.

Me reitero en todo lo dicho anteriormente, tu último mensaje lo unico que hace es confirmar de nuevo las ventajas de trabajar con clases.

Ya me he copiado todo el mensaje que has puesto, ademas de la url del post y tus datos, para que, en cuanto me ponga con ello (que va a ser muy pronto), si tengo alguna duda, te consultaré.

Un saludo.
  #10 (permalink)  
Antiguo 07/09/2011, 05:39
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

Hola de nuevo.

No he podido resistirme a empezar con las clases y despues de un rato, me ha salido esto.

Hay tres archivos. El primero que contiene las clases

Código PHP:
Ver original
  1. <?php
  2. class conectar
  3. {
  4.     public static function con()
  5.     {
  6.         $conexion=mysql_connect("localhost","root","");
  7.         mysql_select_db("cuentas",$conexion);
  8.         return $conexion;
  9.     }
  10. }
  11.  
  12. class gestor_errores
  13. {
  14.     public static function ejecuto_error($num_error,$txt_error)
  15.     {
  16.         //$_SESSION['numero_error'] = mysql_errno(conectar::con());
  17.         //$_SESSION['texto_error'] = mysql_error(conectar::con());
  18.  
  19.         $_SESSION['numero_error'] = $num_error;
  20.         $_SESSION['texto_error'] = $txt_error;
  21.  
  22.         header("Location:probando.php");
  23.     }
  24. }
  25.  
  26. class consultas
  27. {
  28.     //Atributos para las funciones
  29.     private $sql;
  30.     private $result;
  31.     private $error;
  32.  
  33.     //Constructor: Inicializo la variable sql
  34.     public function __construct()
  35.     {
  36.         $this->result=array();
  37.     }
  38.     //Consultas de seleccion SELECT
  39.     public function seleccion($sql)
  40.     {
  41.         $rs=mysql_query($sql,conectar::con()) or die (gestor_errores::ejecuto_error(mysql_errno(),mysql_error()));
  42.         //Si la conexion es fallida, llamo a gestion de errores
  43.  
  44.        
  45.         while ($rs1=mysql_fetch_assoc($rs))
  46.         {
  47.             $this->result[]=$rs1;
  48.         }
  49.         return $this->result;
  50.     }
  51.    
  52.     //Consultas de insercion UPDATE
  53.     public function insercion()
  54.     {
  55.        
  56.     }
  57.    
  58.     //Consultas de eliminacion DELETE
  59.     public function eliminacion()
  60.     {
  61.        
  62.     }
  63.    
  64.     //Consultas de modificacion UPDATE
  65.     public function modificacion()
  66.     {
  67.        
  68.     }
  69. }
  70. ?>
el segundo recibe los datos de una consulta

Código PHP:
Ver original
  1. <?php
  2. include_once('clases.php');
  3.  
  4.  
  5. $cons = new consultas();
  6. $sql = "SELECT * FROM t_sconceptos";
  7. $cons1 = $cons->seleccion($sql);
  8.  
  9. for ($i=0;$i<count($cons1);$i++)
  10. {
  11.     echo 'ID_CONCEPTO: '.$cons1[$i]['id_concepto'];
  12.     echo '<br>';
  13.    
  14.     echo 'CONCEPTO: '.$cons1[$i]['concepto'];
  15.     echo '<br>';
  16.    
  17.     echo 'TIPO CONCEPTO: '.$cons1[$i]['tipo_concepto'];
  18.     echo '<hr>';
  19. }
  20. ?>

El tercero muestra los errores en el caso de que los haya

Código PHP:
Ver original
  1. <?php
  2.  
  3. echo $_SESSION['numero_error'];
  4. echo '<br>';
  5. echo $_SESSION['texto_error'];
  6. echo '<br>';
  7.  
  8. ?>

Me ha costado que me funcione, pero al final funciona.

Con respecto a los comentarios de vgonga, he seguido un camino diferente al que el me había indicado, pero bueno, estoy comenzando con las clases.

Bueno, admito sugerencias al respecto, es decir, a ver que os parece y si se puede mejorar, que imagino que si.

Un saludo.
  #11 (permalink)  
Antiguo 07/09/2011, 06:16
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Control de errores como Dios manda

Yo fusionaría conectar y consultas, al fin y al cabo no dejan de ser operaciones que se realizan contra una base de datos, la conexión se puede tomar también como una operación de este tipo. Pero vamos, es más que nada tema de conceptos, el cuanto a programación, lo veo bien.

Es buena idea el tema de tratar los errores en otra página diferente, pasándolos por SESSION, así además podrás añadir textos privados a los errores. Yo no lo tengo así, porque siempre muestro los errores en la misma página, pero de forma controlada (por eso te lo aconsejé en ese otro sentido). Básicamente, lo que hago es dejar un div para los errores al principio de la zona en que puedan darse, por ejemplo, un formulario o una tabla de presentación de resultados. En caso de que hay error, imprimo el error en ese div y lo hago visible, pero siempre en la misma página. Tú lo has planteado de otra forma, pero es tan buena idea una como otra.

Un saludo y suerte, te veo interesado con este tema.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #12 (permalink)  
Antiguo 07/09/2011, 09:22
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

Hola.

Respecto a lo que comentas, la idea principal era mostrar los errores en la misma pagina, pero cuando usaba or die, lo que hacia era dejar de leer el codigo (como exit) y me lo descolocaba todo, ademas de imprimir el error en el primer sitio que cogia, y por eso decidií mostrarlos en otra pagina.

Con respecto a lo demas, bueno, la idea es incrementar estas clases, para por ejemplo, hacer otras funciones para conectar a otras bd, incrementar las funciones de consultas, por ejemplo, en las de seleccion, una con while y otra sin el, etc, etc, etc.

Un saludo.
  #13 (permalink)  
Antiguo 07/09/2011, 09:42
Avatar de vgonga1986  
Fecha de Ingreso: marzo-2008
Ubicación: País de Pandereta
Mensajes: 1.021
Antigüedad: 16 años, 1 mes
Puntos: 253
Respuesta: Control de errores como Dios manda

Buenas,

No has entendido bien el or die, jejeje... No es un invento, es una operación lógica como otra cualquiera.
A or B

Si A se evalúa a true, ya no evalúa B. Si A se evalúa a false, entonces sigue con la parte de B. Si tú pones esto:
Código PHP:
Ver original
  1. mysql_query("...") or die("...");

Lo que estás haciendo es que tu A es mysql_query() y tu B es die(), con una operación lógica or en medio. Qué hace esto:
- Si mysql_query se ejecuta correctamente, devuelve algo que es distinto de false y ya no evalúa la parte B, porque el or ya resulta true. Sólo ejecutas el query.
- Si mysql_query da algún error, entonces devuelve false. Como ha devuelto false, PHP tiene que seguir evaluando la operación lógica, para ver si da false o true, por lo que ejecuta la parte B. Y qué tienes en la parte B? Un die(). Luego mata el proceso, mostrando el mensaje que le pongas.

Esto se podría traducir así:
Código PHP:
Ver original
  1. if (!mysql_query("...")) {
  2.    die("...");
  3. }

Para que el error lo muestre en la página, pero no finalice la ejecución del script tendrías que hacer lo siguiente:
Código PHP:
Ver original
  1. if (!mysql_query("...")) {
  2.    echo "...";
  3. }

O, lo que es lo mismo:
Código PHP:
Ver original
  1. mysql_query("...") or echo "...";

La gente utiliza tanto eso junto que le parece que es un invento de PHP, pero es tan simple como eso que he explicado. No es ninguna panacea y se puede usar como se quiera. De hecho, puedes hacer algo parecido con el AND, pero con un detalle. El and normal en PHP se pone &&, esto evalúa todas las opciones, si utilizas & deja de evaluar cuando encuentra un false. Por ejemplo:
Código PHP:
Ver original
  1. if (!isset($variable) && $variable = 0)

Esto podría dar un error no controlado, ya que si no está declarada $variable, la primera parte da false, pero la segunda te da error de PHP, porque estás intentando acceder a $variable y no existe. Sin embargo, si haces así:
Código PHP:
Ver original
  1. if (!isset($variable) & $variable = 0)

Nunca te va a dar error, porque si $variable no está declara, la primera comprobación da false y, directamente, no evalúa la segunda, por lo que estás a salvo.

Consejillos y detallitos que no suelen aparecer en los manuales.

Un saludo.
__________________
¿Alguna pregunta, duda, acotación, nota, cuestión, reparo, comentario, demanda, crítica, interpretación, objeción, interrogante, discrepancia, observación, réplica, disquisición, apostilla o exégesis?
  #14 (permalink)  
Antiguo 07/09/2011, 09:57
 
Fecha de Ingreso: mayo-2009
Mensajes: 742
Antigüedad: 15 años
Puntos: 6
Respuesta: Control de errores como Dios manda

No, la verdad es que no me lo planteé así.

Creo que esta cambia algunas cosas, las cuales aplicaré enseguida.

Gracias de nuevo por compartir tus conocimientos, yo creo que con todo lo que se ha comentado en este post es facil extraer varias buenas ideas.

Un saludo.

Etiquetas: control, errores, mysql, tabla, usuarios
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 20:39.