Подтвердить что ты не робот

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 фиксирует все ошибки, связанные с полным выполнением запроса, который он определяет?

Спасибо С

4b9b3361

Ответ 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 из вашего запроса.

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