2008-09-06 14 views
10

Estoy tratando con una tabla MySQL que define la columna JobName como ÚNICA. Si alguien intenta guardar un nuevo trabajo en la base de datos usando un JobName que ya está en la base de datos, MySQL arroja una advertencia.¿Puedo detectar y manejar advertencias de MySQL con PHP?

Me gustaría poder detectar esta advertencia, al igual que un error, en mi script PHP y tratarlo adecuadamente. Idealmente, me gustaría saber qué tipo de advertencia ha lanzado MySQL para poder ramificar el código para manejarlo.

¿Esto es posible? Si no, ¿es porque MySQL no tiene esta capacidad, PHP no tiene esta capacidad, o ambas cosas?

Respuesta

10

Para que las advertencias sean "marcadas" a PHP de forma nativa, se requerirían cambios en el controlador mysql/mysqli, lo que obviamente está más allá del alcance de esta pregunta. En vez vas a tener que comprobar básicamente todas las consultas que realice en la base de datos para las advertencias:

$warningCountResult = mysql_query("SELECT @@warning_count"); 
if ($warningCountResult) { 
    $warningCount = mysql_fetch_row($warningCountResult); 
    if ($warningCount[0] > 0) { 
     //Have warnings 
     $warningDetailResult = mysql_query("SHOW WARNINGS"); 
     if ($warningDetailResult) { 
      while ($warning = mysql_fetch_assoc(warningDetailResult) { 
       //Process it 
      } 
     } 
    }//Else no warnings 
} 

Obviamente, esto va a ser terriblemente caro para aplicar en-masa, por lo que puede que tenga que pensar cuidadosamente acerca de cuándo y cómo pueden surgir advertencias (lo que puede llevarlo a la refactorización para eliminarlas).

Como referencia, MySQL SHOW WARNINGS

Por supuesto, se puede prescindir de la consulta inicial para el SELECT @@warning_count, que le ahorraría una consulta por cada ejecución, pero se incluye por completo pedante.

+0

O use el controlador MySQLi, que tiene una propiedad warning_count. http://php.net/manual/en/mysqli.warning-count.php –

4

En primer lugar, debe turn warnings off para que sus visitantes no vean sus errores de MySQL. En segundo lugar, cuando llamas al mysql_query(), debes verificar si el resultado es falso. Si lo hizo, llame al mysql_errno() para averiguar qué salió mal. Haga coincidir el número devuelto con los códigos de error en this page.

Parece que este es el número de error que estás buscando:

Error: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)

Message: Can't write, because of unique constraint, to table '%s'

+5

Si no me equivoco, pregunta por las advertencias, no por los errores. Una advertencia todavía permite que la consulta pase y, por lo tanto, 'mysql_query' no devolverá' false'. Vea la respuesta de iAn para el soporte de advertencia limitado de PHP. – Andrew

0

actualizado para eliminar la materia acerca de las funciones errno que ahora me doy cuenta, no se aplican en su situación ...

Una cosa en MySQL es tener cuidado con las declaraciones UPDATE: mysqli_affected_rows() devolverá cero incluso si la cláusula WHERE coincidió con las filas, pero la cláusula SET en realidad no modificó los valores de los datos. Solo menciono esto porque ese comportamiento causó una falla en un sistema que una vez miré: el programador usó ese valor de retorno para verificar los errores después de una actualización, suponiendo que un cero significaba que se había producido algún error. Simplemente significaba que el usuario no cambió ningún valor existente antes de hacer clic en el botón de actualización.

Supongo que usar mysqli_affected_rows() no se puede confiar en que encuentre tales advertencias, a menos que tenga algo como una columna update_time en su tabla que siempre se le asignará un nuevo valor de marca de tiempo cuando se actualice. Sin embargo, ese tipo de solución parece algo kludgey.

0

dependiendo de qué marco (si lo hay) que está utilizando, le sugiero que haga una consulta para verificar el nombre del trabajo usted mismo y cree la información adecuada para el usuario con el resto de las validaciones para el formulario.

Dependiendo del número de nombres de puestos, puede enviar los nombres a la vista que contiene el formulario y usar javascript para indicar el uso que se realiza.

Si esto no tiene sentido para usted, entonces, para resumir mi punto de vista, esto es así: no diseñe su programa y/o usuario para tratar de hacer cosas ilegales y detectar los errores cuando lo hagan y manejarlos. Es mucho mejor, yo también, diseñar tu sistema para que no cree errores. Mantenga los errores en errores reales :)

0

Puede detectar infracciones de clave únicas utilizando el error de declaración mysqli no. La instrucción mysqli devuelve el error 1062, que es ER_DUP_ENTRY. Puede buscar el error 1062 e imprimir un mensaje de error adecuado. Si desea imprimir su columna (jobName) también como parte de su mensaje de error, entonces debe analizar la cadena de error de la declaración.

 
    if($stmt = $mysqli->prepare($sql)){ 
      $stmt->bind_param("sss", 
      $name, 
      $identKey, 
      $domain); 


      $stmt->execute(); 
      if($mysqli->affected_rows != 1) { 
         //This will return errorno 1062 
       trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR); 
       exit(1); 
      } 
      $stmt->close(); 
     } else { 

      trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR); 
     } 
0

Es posible obtener las advertencias, y de una manera más eficiente con mysqli que con mysql.

Este es el código sugerido en el manual de page en php.net para la propiedad mysqli-> warning_count:

$mysqli->query($query); 

if ($mysqli->warning_count) { 
    if ($result = $mysqli->query("SHOW WARNINGS")) { 
     $row = $result->fetch_row(); 
     printf("%s (%d): %s\n", $row[0], $row[1], $row[2]); 
     $result->close(); 
    } 
} 
0

Nota sobre la supresión de advertencias: En general, no es una buena idea para evitar advertencias de ser mostrado ya que es posible que te falte algo importante. Si por alguna razón tiene que ocultar las advertencias, puede hacerlo de forma individual colocando un signo @ delante de la declaración. De esta forma, no tiene que desactivar todos los informes de advertencia y puede limitarlo a una instancia específica.

Ejemplo:

// this suppresses warnings that might result if there is no field titled "field" in the result 
$field_value = @mysql_result($result, 0, "field"); 
+1

Parece que el usuario quiere poder detectar el error, no suprimirlo. – pgreen2

+0

Es una idea mucho mejor usar 'ini_set ('display_errors', 0);' (mejor aún, póngalo en su php.ini), de esa forma los usuarios no verán nada que pueda suponer un riesgo de seguridad. Junto con eso, recomendaría asegurarme de que 'error_log' esté configurado en un archivo escribible y configure' error_reporting = -1' para que se conozcan todos los problemas potenciales. –

3
ini_set('mysql.trace_mode', 1) 

puede ser lo que buscas.

Los errores de PHP pueden manejarse con un manejador de errores PHP personalizado, pero también puede desactivar la visualización de los errores de php ya que generalmente se registran en un archivo de registro (depende de su configuración de php).

Cuestiones relacionadas