У меня есть страница на моем сайте (высокий трафик), которая делает вставку при каждой загрузке страницы.
Мне интересен самый быстрый и безопасный способ (поймать ошибку) и продолжить, если система не в состоянии выполнить вставку в 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); ...
Проверка документации показывает, что она возвращает 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
Это может сделать трюк,
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()); }
Вы можете реализовать исключения бросания в запросе 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(); }
если вы хотите зарегистрировать ошибку и т. д., вы должны использовать try / catch, если вы этого не сделали; просто поставьте @ перед mysql_query
edit: вы можете использовать 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; }
yasaluyari
ответ на 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
для проверки, потому что наша функция теперь обрабатывает ее сама по себе. И так же, как он обрабатывает выборки, он просто присваивает результат переменной, как и нормальная функция, но обрабатывает ошибки внутри себя.
Также обратите внимание: нам не нужно показывать фактические ошибки, так как они несут огромный риск для безопасности, особенно с этим устаревшим расширением. Вот почему наш дефолт будет очень хорош в большинстве случаев. Тем не менее, если мы хотим уведомить пользователя о какой-либо конкретной ошибке запроса, мы всегда можем передать второй параметр, чтобы отобразить наше сообщение об ошибке.
$sql = "INSERT INTO customer(FIELDS)VALUES(VALUES)"; mysql_query($sql); if (mysql_errno()) { echo "<script>alert('License already registered');location.replace('customerform.html');</script>"; }
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Я не уверен, есть ли версия mysql, но добавление этой строки кода позволяет бросать mysqli_sql_exception.
Я знаю, прошло много времени, и вопрос уже проверен, но я получил другой ответ, и это может быть полезно.
Используйте любой метод, описанный в предыдущем сообщении, чтобы как-то уловить ошибку 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) { .... }
не будет работать!
Примечание. Не имеет прямого отношения к вашему вопросу, но я думаю, что это было бы намного лучше, если бы вы отображали что-то полезное для пользователя. Я бы никогда не пересматривал сайт, который просто отображает пустой экран или любое загадочное сообщение об ошибке.