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);
...
8 ответов

Проверка документации показывает, что возвращается 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

изменить: вы можете использовать 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, я бы придерживался примерно следующего:

Мы можем просто изменить наш 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 "";
 }


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) { .... } не будет работать!

Примечание. Не имеет прямого отношения к вам, но я думаю, что это будет намного лучше, если вы выберете что-то полезное для пользователя. Я бы никогда не пересматривал сайт, который просто отображает пустой экран или любое загадочное сообщение об ошибке.

licensed under cc by-sa 3.0 with attribution.