php - statement - MySQLi preparó el informe de error de declaraciones
sentencias preparadas php mysqli (3)
Esta pregunta ya tiene una respuesta aquí:
Estoy tratando de entender MySQli y estoy confundido por el informe de errores. Estoy usando el valor de retorno de la declaración ''prepare'' de MySQLi para detectar errores al ejecutar SQL, así:
$stmt_test = $mysqliDatabaseConnection->stmt_init();
if($stmt_test->prepare("INSERT INTO testtable VALUES (23,44,56)"))
{
$stmt_test->execute();
$stmt_test->close();
}
else echo("Statement failed: ". $stmt_test->error . "<br>");
Pero, ¿el valor de retorno de la declaración de preparación solo detecta si hay un error en la preparación de la declaración SQL y no detecta errores de ejecución? Si es así, por lo tanto, debería cambiar mi línea de ejecución para marcar errores así como esto:
if($stmt_test->execute()) $errorflag=true;
Y para estar seguro también debería hacer lo siguiente después de que se haya ejecutado la declaración:
if($stmt_test->errno) {$errorflag=true;}
... ¿O estaba bien para empezar y el valor de retorno en la declaración MySQLi prepare ''captura todos los errores asociados con la ejecución completa de la consulta que define?
Gracias c
Lo escribí dos veces antes en los últimos dos días (así que para mí es un duplicado, aunque las preguntas comenzaron un poco diferente).
Cada método de mysqli puede fallar. Debe probar cada valor de retorno. Si uno falla, piense si tiene sentido continuar con un objeto que no está en el estado que espera que sea. (Potencialmente no en un estado "seguro", pero creo que no es un problema aquí).
Como solo se almacena el mensaje de error de la última operación por conexión / declaración, es posible que pierda información sobre lo que causó el error si continúa después de que algo salió mal. Es posible que desee utilizar esa información para dejar que el guión decida si volver a intentarlo (solo un problema temporal), cambiar algo o rescatar por completo (e informar un error). Y hace que la depuración sea mucho más fácil.
$stmt = $mysqli->prepare("INSERT INTO testtable VALUES (?,?,?)");
// prepare() can fail because of syntax errors, missing privileges, ....
if ( false===$stmt ) {
// and since all the following operations need a valid/ready statement object
// it doesn''t make sense to go on
// you might want to use a more sophisticated mechanism than die()
// but''s it''s only an example
die(''prepare() failed: '' . htmlspecialchars($mysqli->error));
}
$rc = $stmt->bind_param(''iii'', $x, $y, $z);
// bind_param() can fail because the number of parameter doesn''t match the placeholders in the statement
// or there''s a type conflict(?), or ....
if ( false===$rc ) {
// again execute() is useless if you can''t bind the parameters. Bail out somehow.
die(''bind_param() failed: '' . htmlspecialchars($stmt->error));
}
$rc = $stmt->execute();
// execute() can fail for various reasons. And may it be as stupid as someone tripping over the network cable
// 2006 "server gone away" is always an option
if ( false===$rc ) {
die(''execute() failed: '' . htmlspecialchars($stmt->error));
}
$stmt->close();
editar: solo unas pocas notas seis años después ...
La extensión mysqli es perfectamente capaz de informar operaciones que dan como resultado un código de error (mysqli) distinto de 0 a través de excepciones, consulte mysqli_driver::$report_mode .
die() es realmente, muy crudo y no lo usaría ni siquiera para ejemplos como este.
Por lo tanto, solo elimine el hecho de que todas y cada una de las operaciones (mysql) pueden fallar por varias razones; incluso si exactamente lo mismo fue bien mil veces antes ...
No estoy seguro si esto responde su pregunta o no. Lo siento si no
Para obtener el error informado de la base de datos mysql acerca de su consulta, debe usar su objeto de conexión como foco.
asi que:
echo $mysqliDatabaseConnection->error
repetiría el error enviado desde mysql sobre su consulta.
Espero que ayude
Lo completo
$mysqli
verificar tanto $mysqli
como $statement
. Si son falsos, debe generar $mysqli->error
o $statement->error
respectivamente.
Eficiencia
Para las secuencias de comandos simples que pueden terminar, utilizo líneas simples que desencadenan un error de PHP con el mensaje. Para una aplicación más compleja, un sistema de advertencia de error debería activarse en su lugar, por ejemplo lanzando una excepción.
Ejemplo de uso 1: script simple
# This is in a simple command line script
$mysqli = new mysqli(''localhost'', ''buzUser'', ''buzPassword'');
$q = "UPDATE foo SET bar=1";
($statement = $mysqli->prepare($q)) or trigger_error($mysqli->error, E_USER_ERROR);
$statement->execute() or trigger_error($statement->error, E_USER_ERROR);
Ejemplo de uso 2: aplicación
# This is part of an application
class FuzDatabaseException extends Exception {
}
class Foo {
public $mysqli;
public function __construct(mysqli $mysqli) {
$this->mysqli = $mysqli;
}
public function updateBar() {
$q = "UPDATE foo SET bar=1";
$statement = $this->mysqli->prepare($q);
if (!$statement) {
throw new FuzDatabaseException($mysqli->error);
}
if (!$statement->execute()) {
throw new FuzDatabaseException($statement->error);
}
}
}
$foo = new Foo(new mysqli(''localhost'',''buzUser'',''buzPassword''));
try {
$foo->updateBar();
} catch (FuzDatabaseException $e)
$msg = $e->getMessage();
// Now send warning emails, write log
}