Могу ли я обнаруживать и обрабатывать предупреждения MySQL с помощью PHP?
Я имею дело с таблицей MySQL, которая определяет столбец JobName как UNIQUE. Если кто-то пытается сохранить новое задание в базе данных с использованием JobName, которое уже находится в базе данных, MySQL выдает предупреждение.
Я хотел бы иметь возможность обнаружить это предупреждение, точно так же как и ошибку, в моем PHP script и справиться с ним соответствующим образом. В идеале я хотел бы знать, какое предупреждение вышло MySQL, чтобы я мог обработать код для его обработки.
Возможно ли это? Если нет, это потому, что MySQL не обладает этой способностью, PHP не обладает этой способностью или оба?
Ответы
Ответ 1
Для предупреждений, которые должны быть "помечены" для PHP, изначально потребовались бы изменения в драйвере mysql/mysqli, что явно выходит за рамки этого вопроса. Вместо этого вам придется в основном проверить каждый запрос, который вы делаете в базе данных, для предупреждений:
$warningCountResult = mysql_query("SELECT @@warning_count");
if ($warningCountResult) {
$warningCount = mysql_fetch_row($warningCountResult );
if ($warningCount[0] > 0) {
//Have warnings
$warningDetailResult = mysql_query("SHOW WARNINGS");
if ($warningDetailResult ) {
while ($warning = mysql_fetch_assoc(warningDetailResult) {
//Process it
}
}
}//Else no warnings
}
Очевидно, что это будет ужасно дорого для применения en-mass, поэтому вам может потребоваться тщательно подумать о том, когда и как могут возникнуть предупреждения (что может привести к рефактору для их устранения).
Для справки MySQL SHOW WARNINGS
Конечно, вы можете обойтись без первоначального запроса для SELECT @@warning_count
, который сохранит вам запрос за выполнение, но я включил его для полноты педантичности.
Ответ 2
Во-первых, вы должны отключить предупреждения, чтобы ваши посетители не видели ваши ошибки MySQL. Во-вторых, когда вы вызываете mysql_query()
, вы должны проверить, вернули ли он false. Если это так, позвоните mysql_errno()
, чтобы узнать, что пошло не так. Сопоставьте номер, возвращенный кодам ошибок на этой странице.
Похоже, это номер ошибки, которую вы ищете:
Ошибка: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)
Сообщение: не удается записать из-за уникального ограничения в таблицу '% s'
Ответ 3
ini_set('mysql.trace_mode', 1)
может быть тем, что вы ищете.
Затем ошибки PHP могут обрабатываться с помощью специального обработчика ошибок PHP, но вы также можете просто отключить отображение ошибок php, поскольку они обычно регистрируются в файле журнала (зависит от вашей конфигурации php).
Ответ 4
Обновлено для удаления информации о функциях errno, которые я теперь понимаю, не применяются в вашей ситуации...
Одна вещь в MySQL, которую следует опасаться для операторов UPDATE
: mysqli_affected_rows()
будет возвращать ноль, даже если соответствующие строки WHERE
соответствуют строкам, но предложение SET
фактически не изменило значения данных. Я упоминаю об этом только потому, что это поведение вызвало ошибку в системе, которую я когда-то смотрел - программист использовал это возвращаемое значение для проверки ошибок после обновления, предполагая, что нуль означает, что произошла какая-то ошибка. Это просто означало, что пользователь не изменял никаких существующих значений перед нажатием кнопки обновления.
Таким образом, я полагаю, что использование mysqli_affected_rows()
не может быть использовано для поиска таких предупреждений, если только у вас есть что-то вроде столбца update_time
в вашей таблице, которому при обновлении всегда будет назначаться новое значение метки времени. Однако такое обходное решение кажется любезным kludgey.
Ответ 5
в зависимости от того, какую (если есть) структуру, которую вы используете, я предлагаю вам выполнить запрос, чтобы проверить имя задания самостоятельно и создать правильную информацию для пользователя с остальными валидациями для формы.
В зависимости от количества рабочих имен вы можете отправить имена в представление, содержащее форму, и использовать javascript для указания использования, которое было принято.
Если это не имеет смысла для вас, то суммируйте мой взгляд на это: не создавайте свою программу и/или пользователей, чтобы пытаться делать нелегальные вещи и ловить ошибки, когда они это делают и обрабатывают. Намного лучше, imho, создать вашу систему, чтобы не создавать ошибок. Храните ошибки в действительных ошибках:)
Ответ 6
Вы можете обнаружить уникальные нарушения ключей с помощью ошибки mysqli no. Оператор mysqli возвращает ошибку 1062, то есть ER_DUP_ENTRY. Вы можете найти ошибку 1062 и напечатать подходящее сообщение об ошибке. Если вы хотите напечатать свой столбец (имя_пользователя) также как часть вашего сообщения об ошибке, вы должны проанализировать строку ошибки оператора.
if($stmt = $mysqli->prepare($sql)){
$stmt->bind_param("sss",
$name,
$identKey,
$domain);
$stmt->execute();
if($mysqli->affected_rows != 1) {
//This will return errorno 1062
trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR);
exit(1);
}
$stmt->close();
} else {
trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR);
}
Ответ 7
Можно получить предупреждения и более эффективно с помощью mysqli, чем с mysql.
Вот код, предложенный в руководстве страница на php.net для свойства mysqli- > warning_count:
$mysqli->query($query);
if ($mysqli->warning_count) {
if ($result = $mysqli->query("SHOW WARNINGS")) {
$row = $result->fetch_row();
printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
$result->close();
}
}
Ответ 8
Примечание по подавлению предупреждений: Как правило, не рекомендуется предотвращать отображение предупреждений, так как вы можете пропустить что-то важное. Если вы по какой-то причине обязательно должны скрывать предупреждения, вы можете сделать это индивидуально, поставив перед тегом знак @
. Таким образом, вам не нужно отключать все предупреждения и ограничивать их конкретным экземпляром.
Пример:
// this suppresses warnings that might result if there is no field titled "field" in the result
$field_value = @mysql_result($result, 0, "field");