MySQLi подготовил отчеты об ошибках отчетов
Я пытаюсь разгадать MySqli, и я смущен сообщением об ошибках.
Я использую возвращаемое значение инструкции MySQLi "подготовить" для обнаружения ошибок при выполнении SQL, например:
$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>");
Но, является ли возвращаемое значение оператора подготовки только обнаружением ошибки в выполнении инструкции SQL и не обнаружения ошибок выполнения? Если это так, я поэтому должен изменить мою строку выполнения так, чтобы они отображали ошибки:
if($stmt_test->execute()) $errorflag=true;
И тогда, чтобы быть в безопасности, я также должен сделать следующее после выполнения инструкции:
if($stmt_test->errno) {$errorflag=true;}
... Или я был в порядке, и возвращаемое значение в операторе подготовки MySQLi фиксирует все ошибки, связанные с полным выполнением запроса, который он определяет?
Спасибо
С
Ответы
Ответ 1
Я написал это дважды ранее в течение последних двух дней (так что для меня это дубликат, хотя вопросы начали немного по-другому).
Каждый метод mysqli может выйти из строя. Вы должны проверить каждое возвращаемое значение. Если кто-то терпит неудачу, подумайте о том, имеет ли смысл продолжать объект, который не находится в состоянии, которое вы ожидаете от него. (Потенциально не в "безопасном" состоянии, но я думаю, что здесь не проблема).
Так как только сообщение об ошибке для последней операции хранится для каждого соединения/оператора, вы можете потерять информацию о том, что вызвало ошибку, если вы продолжаете после того, как что-то пошло не так. Возможно, вы захотите использовать эту информацию, чтобы позволить script решить, следует ли повторять попытку (только временную проблему), изменить что-либо или полностью выпустить (и сообщить об ошибке). И это облегчает отладку.
$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 it 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 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();
изменить: всего несколько нот через шесть лет....
Расширение mysqli отлично способно выполнять операции, которые приводят к ошибке (mysqli), отличному от 0 через исключения, см. mysqli_driver:: $report_mode.
die() действительно очень груб, и я бы не использовал его даже для таких примеров, как этот.
Поэтому, пожалуйста, уберите только тот факт, что каждая операция (mysql) может завершиться неудачей по ряду причин; даже если точно такая же вещь прошла тысячу раз раньше....
Ответ 2
Полнота
Вам нужно проверить как $mysqli
, так и $statement
. Если они ложны, вам нужно вывести $mysqli->error
или $statement->error
соответственно.
Эффективность
Для простых сценариев, которые могут завершиться, я использую простые однострочные, которые вызывают ошибку PHP с сообщением. Для более сложного приложения вместо этого необходимо активировать систему предупреждения об ошибках, например, путем исключения исключения.
Пример использования 1: Простой script
# 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);
Пример использования 2: Приложение
# 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
}
Ответ 3
Не уверен, ответит ли это на ваш вопрос или нет. Извините, если не
Чтобы получить сообщение об ошибке, полученное из базы данных mysql о вашем запросе, вам необходимо использовать объект подключения в качестве фокуса.
так:
echo $mysqliDatabaseConnection->error
будет эхо-ошибка, отправляемая из mysql из вашего запроса.
Надеюсь, что поможет