2009-12-16 26 views
19

que tienen una página en mi sitio web (alto tráfico) que hace una inserción en cada carga de página.PHP tratar de atrapar para SQL Insert

tengo curiosidad de la manera más rápida y segura de (coger un error) y continuar si el sistema no es capaz de hacer el inserto en MySQL. ¿Debo usar try/catch o morir o algo más? Quiero asegurarme de que la inserción ocurra, pero si por algún motivo no puedo, quiero que la página continúe cargándose de todos modos.

... 
$db = mysql_select_db('mobile', $conn); 
mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'") or die('Error #10'); 
mysql_close($conn); 
... 
+0

Sobre el uso de "o morir": http://www.phpfreaks.com/blog/or-die-must-die – outis

+1

En cuanto a las excepciones frente a la comprobación de los valores devueltos, depende de cuántos puntos pueden generar errores. Con uno o dos puntos, iría con la comprobación de errores, ya que es más eficiente y más legible en este caso. Una vez que aciertes tres o más comprobaciones de error en un bloque de código, las excepciones se vuelven más legibles. Se trata de reducir la complejidad ciclomática. Tenga en cuenta que esto cubre el punto en que maneja el error; si habla de errores de señalización, terminará con diferentes pautas. – outis

Respuesta

23

Comprobación de la documentation muestra que sus retornos false en un error. Por lo tanto, use el estado de devolución en lugar de or die(). Devolverá falso si falla, lo cual puede registrar (o lo que quiera hacer) y luego continuar.

$rv = mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'"); 
if ($rv === false){ 
    //handle the error here 
} 
//page continues loading 
+0

¿Eso no arroja un error? –

+1

No creo que mysql_query arroje una excepción. – Yacoby

+8

De hecho, ni 'mysql_query' ni' mysqli_query' arrojan una excepción. 'PDOStatement :: execute' lo hará, pero solo si llama a' PDO :: setAttribute (PDO :: ATTR_ERRMODE, PDO :: ERRMODE_EXCEPTION) 'antes de llamar a' PDOStatement :: execute'. – outis

5

si desea registrar el error, etc. debe usar try/catch, si no lo hace; sólo hay que poner antes de @ mysql_query

edición: puede utilizar intento de captura como esto; por lo que puede registrar el error y dejar que continúe la página para cargar

function throw_ex($er){ 
    throw new Exception($er); 
} 
try { 
mysql_connect(localhost,'user','pass'); 
mysql_select_db('test'); 
$q = mysql_query('select * from asdasda') or throw_ex(mysql_error()); 
} 
catch(exception $e) { 
    echo "ex: ".$e; 
} 
+0

la función mysql no arroja ninguna excepción. – TheHippo

+0

Gran ejemplo, esta parece ser la forma más adecuada de hacerlo, y voy a seguir con eso también. La ventaja es obvia: te darás cuenta de cuándo tendrás que hacer 5 consultas en un bloque y saldrás corriendo si alguno de ellos falla con una excepción. Me gustaría profundizar en eso por un tiempo. – Anonymous

+0

Buen ejemplo y buena forma, resultado para mi caso: ej: excepción 'Excepción' con el mensaje 'Entrada duplicada' 4 'para la clave' PRIMARIO '' en. Gracias – Phiber

-1

Use cualquier método descrito en el post anterior para coger alguna manera el error de MySQL.
más común es:

$res = mysql_query('bla'); 
if ($res===false) { 
    //error 
    die(); 
} 
//normal page 

Esto también funcionaría:

function error() { 
    //error 
    die() 
} 
$res = mysql_query('bla') or error(); 
//normal page 

try { ... } catch {Exception $e) { .... } no va a funcionar!

Nota: no relacionados directamente con usted pregunta, pero creo que sería mucho más mejor si muestra algo útil para el usuario. Nunca volvería a visitar un sitio web que solo muestra una pantalla en blanco o un misterioso mensaje de error.

10

Esto puede hacer el truco,

function createLog($data){ 
    $file = "Your path/incompletejobs.txt"; 
    $fh = fopen($file, 'a') or die("can't open file"); 
    fwrite($fh,$data); 
    fclose($fh); 
} 
$qry="INSERT INTO redirects SET ua_string = '$ua_string'" 
$result=mysql_query($qry); 
if(!$result){ 
    createLog(mysql_error()); 
} 
+0

Esto funciona perfectamente. –

+0

@DjangoReinhardt Gracias y estoy contento de ayudar a alguien ... – VKGS

+0

@Sekar complicado ... –

2

Abundando en respuesta yasaluyari 's me gustaría seguir con algo como esto:

sólo podemos modificar nuestra mysql_query de la siguiente manera:

function mysql_catchquery($query,$emsg='Error submitting the query'){ 
    if ($result=mysql_query($query)) return $result; 
    else throw new Exception($emsg); 
} 

Ahora podemos simplemente utilizar de esta manera, un buen ejemplo:

try { 
    mysql_catchquery('CREATE TEMPORARY TABLE a (ID int(6))'); 
    mysql_catchquery('insert into a values(666),(418),(93)'); 
    mysql_catchquery('insert into b(ID, name) select a.ID, c.name from a join c on a.ID=c.ID'); 
    $result=mysql_catchquery('select * from d where ID=7777777'); 
    while ($tmp=mysql_fetch_assoc($result)) { ... } 
} catch (Exception $e) { 
    echo $e->getMessage(); 
} 

Tenga en cuenta lo hermoso que es. Cada vez que cualquiera de los qq falla, nos encontramos con nuestros errores. Y también puede observar que no necesitamos ahora almacenar el estado de las consultas de escritura en una variable $result para la verificación, porque nuestra función ahora lo maneja por sí mismo. Y de la misma manera que maneja las selecciones, simplemente asigna el resultado a una variable como lo hace la función normal, pero maneja los errores dentro de ella.

También tenga en cuenta, no es necesario para mostrar los errores reales, ya que tienen gran riesgo para la seguridad, sobre todo por lo que con esta extensión obsoleta. Es por eso que nuestro valor predeterminado estará bien la mayor parte del tiempo. Sin embargo, si queremos notificar al usuario sobre algún error de consulta en particular, siempre podemos pasar el segundo parámetro para mostrar nuestro mensaje de error personalizado.

6

Puede implementar implementaciones de excepciones en consultas mysql fallas por su cuenta. Lo que necesita es escribir un envoltorio para la función mysql_query, por ejemplo .:

// user defined. corresponding MySQL errno for duplicate key entry 
const MYSQL_DUPLICATE_KEY_ENTRY = 1022; 

// user defined MySQL exceptions 
class MySQLException extends Exception {} 
class MySQLDuplicateKeyException extends MySQLException {} 

function my_mysql_query($query, $conn=false) { 
    $res = mysql_query($query, $conn); 
    if (!$res) { 
     $errno = mysql_errno($conn); 
     $error = mysql_error($conn); 
     switch ($errno) { 
     case MYSQL_DUPLICATE_KEY_ENTRY: 
      throw new MySQLDuplicateKeyException($error, $errno); 
      break; 
     default: 
      throw MySQLException($error, $errno); 
      break; 
     } 
    } 
    // ... 
    // doing something 
    // ... 
    if ($something_is_wrong) { 
     throw new Exception("Logic exception while performing query result processing"); 
    } 

} 

try { 
    mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'") 
} 
catch (MySQLDuplicateKeyException $e) { 
    // duplicate entry exception 
    $e->getMessage(); 
} 
catch (MySQLException $e) { 
    // other mysql exception (not duplicate key entry) 
    $e->getMessage(); 
} 
catch (Exception $e) { 
    // not a MySQL exception 
    $e->getMessage(); 
} 
+0

Lol, hice una respuesta similar hace 10 minutos. – Anonymous

+0

@Anonymous, aquí tiene un enfoque ligeramente diferente: solo lanza una excepción genérica y no sabe qué tipo de excepción se produce. Por supuesto, puede pasar 'errno' como' $ code' (2º parametro de 'Exception') y marcarlo en' catch' block, pero no es tan completo. Es por eso que escribí esta respuesta a pesar de que ya hay 2 respuestas sobre esta cuestión que explotan el contenedor para la expiación de lanzamiento 'mysql_query'. Entonces, sí, es similar, pero no exactamente lo mismo conceptualmente. – Nemoden

+0

Entiendo, el suyo comprende los tipos de errores, mientras que el mío es exclusivamente para el fácil uso. :) – Anonymous

0
$sql = "INSERT INTO customer(FIELDS)VALUES(VALUES)"; 
    mysql_query($sql); 
    if (mysql_errno()) 
    { 
      echo "<script>alert('License already registered');location.replace('customerform.html');</script>"; 
    } 
0
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 

No estoy seguro de si hay una versión de MySQL de esto, pero la adición de esta línea de código permite tirar mysqli_sql_exception.
Lo sé, pasó mucho tiempo y la pregunta ya ha sido verificada, pero recibí una respuesta diferente y puede ser útil.

+0

Sí, puede tener una respuesta diferente. Agregue más detalles a la respuesta, como dónde agregar la línea de código y un enlace que explique el código en detalle. – Ram

+0

Siempre que se use en el archivo php, es posible que pueda capturar mysqli_sql_exceptionS. – starkm