Отчеты об ошибках подготовленных отчетов MySQLi [дубликат]


На этот вопрос уже есть ответ здесь:

Я пытаюсь разобраться в MySQli, и меня смущают сообщения об ошибках. Я использую возвращаемое значение инструкции MySQLi 'prepare' для обнаружения ошибок при выполнении 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>");

Но разве возвращаемое значение инструкции prepare определяет только наличие ошибки в предварительной подготовке инструкции SQL и не обнаруживает ошибок выполнения? Если это так, то я должен изменить свою строку выполнения, чтобы также помечать ошибки следующим образом:

if($stmt_test->execute()) $errorflag=true;

А затем на всякий случай я также должен сделать следующее после выполнения инструкции:

if($stmt_test->errno) {$errorflag=true;}

...Или я был в порядке с самого начала, и возвращаемое значение в инструкции MySQLi prepare' фиксирует все ошибки связанный с полным выполнением запроса, который он определяет?

Спасибо C

Author: MPelletier, 2010-03-31

3 answers

Я писал это дважды за последние два дня (так что для меня это дубликат, хотя вопросы начинались немного по-другому).

Каждый метод mysqli может завершиться неудачей. Вы должны проверить каждое возвращаемое значение. Если один из них потерпит неудачу, подумайте, имеет ли смысл продолжать работу с объектом, который находится не в том состоянии, в котором вы его ожидаете. (Потенциально не в "безопасном" состоянии, но я думаю, что здесь это не проблема.)

Так как только сообщение об ошибке для последней операции сохраняется в подключение/инструкция вы можете потерять информацию о , что вызвало ошибку, если вы продолжите после того, как что-то пошло не так. Возможно, вы захотите использовать эту информацию, чтобы позволить сценарию решить, следует ли повторить попытку (только временная проблема), что-то изменить или полностью выйти из игры (и сообщить об ошибке). И это значительно упрощает отладку.

$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();

Редактировать: всего несколько заметок шесть лет спустя....
Расширение mysqli прекрасно способно сообщать об операциях, которые приводят к (mysqli) код ошибки, отличный от 0, с помощью исключений, см. mysqli_driver::$report_mode.
die() действительно, очень грубо, и я бы больше не использовал его даже для таких примеров, как этот.
Поэтому, пожалуйста, только уберите тот факт, что каждая операция (mysql) может завершиться неудачей по ряду причин; даже , если то же самое происходило тысячу раз раньше....

 105
Author: VolkerK, 2016-03-24 20:59:38

Полнота

Вам нужно проверить как $mysqli, так и $statement. Если они ложны, вам нужно вывести $mysqli->error или $statement->error соответственно.

Эффективность

Для простых сценариев, которые могут завершиться, я использую простые однострочные строки, которые вызывают ошибку PHP с сообщением. Для более сложного приложения вместо этого следует активировать систему предупреждения об ошибках, например, путем создания исключения.

Пример использования 1: Простой сценарий

# 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
}
 13
Author: cmc, 2014-01-08 23:41:34

Не уверен, отвечает ли это на ваш вопрос или нет. Извините, если нет

Чтобы получить сообщение об ошибке из базы данных mysql о вашем запросе, вам нужно использовать объект подключения в качестве фокуса.

Итак:

echo $mysqliDatabaseConnection->error

Повторил бы ошибку, отправленную из mysql о вашем запросе.

Надеюсь, это поможет

 4
Author: andyface, 2010-03-31 12:04:52