PHP Попытка и поимка для вставки SQL
У меня есть страница на моем сайте (высокий трафик), которая делает вставку при каждой загрузке страницы.
Мне интересен самый быстрый и безопасный способ (поймать ошибку) и продолжить, если система не сможет вставить в MySQL. Должен ли я использовать try/catch или die или что-то еще. Я хочу убедиться, что вставка произошла, но если по какой-то причине я не могу, чтобы страница продолжала загружаться в любом случае.
...
$db = mysql_select_db('mobile', $conn);
mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'") or die('Error #10');
mysql_close($conn);
...
Ответы
Ответ 1
Проверка документации показывает, что возвращается false
на ошибку. Поэтому используйте статус возврата, а не or die()
. Он вернет false, если он не удастся, и вы можете выполнить запись (или все, что хотите), а затем продолжить.
$rv = mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'");
if ( $rv === false ){
//handle the error here
}
//page continues loading
Ответ 2
Это может сделать трюк,
function createLog($data){
$file = "Your path/incompletejobs.txt";
$fh = fopen($file, 'a') or die("can't open file");
fwrite($fh,$data);
fclose($fh);
}
$qry="INSERT INTO redirects SET ua_string = '$ua_string'"
$result=mysql_query($qry);
if(!$result){
createLog(mysql_error());
}
Ответ 3
Вы можете реализовать исключения бросания в запросе mysql самостоятельно. Вам нужно написать оболочку для функции mysql_query, например:
// user defined. corresponding MySQL errno for duplicate key entry
const MYSQL_DUPLICATE_KEY_ENTRY = 1022;
// user defined MySQL exceptions
class MySQLException extends Exception {}
class MySQLDuplicateKeyException extends MySQLException {}
function my_mysql_query($query, $conn=false) {
$res = mysql_query($query, $conn);
if (!$res) {
$errno = mysql_errno($conn);
$error = mysql_error($conn);
switch ($errno) {
case MYSQL_DUPLICATE_KEY_ENTRY:
throw new MySQLDuplicateKeyException($error, $errno);
break;
default:
throw MySQLException($error, $errno);
break;
}
}
// ...
// doing something
// ...
if ($something_is_wrong) {
throw new Exception("Logic exception while performing query result processing");
}
}
try {
mysql_query("INSERT INTO redirects SET ua_string = '$ua_string'")
}
catch (MySQLDuplicateKeyException $e) {
// duplicate entry exception
$e->getMessage();
}
catch (MySQLException $e) {
// other mysql exception (not duplicate key entry)
$e->getMessage();
}
catch (Exception $e) {
// not a MySQL exception
$e->getMessage();
}
Ответ 4
если вы хотите зарегистрировать ошибку и т.д., вы должны использовать try/catch, если вы этого не сделали; просто поставьте @перед mysql_query
изменить:
вы можете использовать try catch так: поэтому вы можете зарегистрировать ошибку и продолжить загрузку страницы
function throw_ex($er){
throw new Exception($er);
}
try {
mysql_connect(localhost,'user','pass');
mysql_select_db('test');
$q = mysql_query('select * from asdasda') or throw_ex(mysql_error());
}
catch(exception $e) {
echo "ex: ".$e;
}
Ответ 5
Разрабатывая ответ yasaluyari
, я бы придерживался примерно следующего:
Мы можем просто изменить наш mysql_query следующим образом:
function mysql_catchquery($query,$emsg='Error submitting the query'){
if ($result=mysql_query($query)) return $result;
else throw new Exception($emsg);
}
Теперь мы можем просто использовать его так: хороший пример:
try {
mysql_catchquery('CREATE TEMPORARY TABLE a (ID int(6))');
mysql_catchquery('insert into a values(666),(418),(93)');
mysql_catchquery('insert into b(ID, name) select a.ID, c.name from a join c on a.ID=c.ID');
$result=mysql_catchquery('select * from d where ID=7777777');
while ($tmp=mysql_fetch_assoc($result)) { ... }
} catch (Exception $e) {
echo $e->getMessage();
}
Заметьте, как это красиво. Всякий раз, когда какой-либо из qq терпит неудачу, мы gtfo с нашими ошибками. И вы также можете заметить, что теперь нам не нужно сохранять состояние запросов на запись в переменную $result
для проверки, потому что наша функция теперь обрабатывает ее сама по себе. Точно так же он обрабатывает выборки, он просто присваивает результат переменной, как и нормальная функция, но обрабатывает ошибки внутри себя.
Также обратите внимание: нам не нужно показывать фактические ошибки, так как они несут огромный риск для безопасности, особенно с этим устаревшим расширением. Вот почему наш дефолт будет очень хорош в большинстве случаев. Тем не менее, если мы хотим уведомить пользователя о какой-либо конкретной ошибке запроса, мы всегда можем передать второй параметр для отображения нашего пользовательского сообщения об ошибке.
Ответ 6
$sql = "INSERT INTO customer(FIELDS)VALUES(VALUES)";
mysql_query($sql);
if (mysql_errno())
{
echo "<script>alert('License already registered');location.replace('customerform.html');</script>";
}
Ответ 7
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Я не уверен, есть ли версия mysql, но добавление этой строки кода позволяет бросать mysqli_sql_exception.
Я знаю, прошло много времени, и вопрос уже проверен, но я получил другой ответ, и это может быть полезно.
Ответ 8
Используйте любой метод, описанный в предыдущем сообщении, чтобы как-то уловить ошибку mysql.
Чаще всего:
$res = mysql_query('bla');
if ($res===false) {
//error
die();
}
//normal page
Это также сработает:
function error() {
//error
die()
}
$res = mysql_query('bla') or error();
//normal page
try { ... } catch {Exception $e) { .... }
не будет работать!
Примечание. Не имеет прямого отношения к вам, но я думаю, что это будет намного лучше, если вы выберете что-то полезное для пользователя. Я бы никогда не пересматривал сайт, который просто отображает пустой экран или любое загадочное сообщение об ошибке.