PHP Try和Catch for SQL Insert

时间:2009-12-16 23:51:58

标签: php mysql performance error-handling

我的网站上有一个页面(流量很大),每次加载都会插入一个页面。

我很想知道(捕获错误)最快最安全的方法,如果系统无法插入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);
...

9 个答案:

答案 0 :(得分:25)

检查documentation表示错误返回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

答案 1 :(得分:10)

这可以解决问题,

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());
}

答案 2 :(得分:7)

您可以自行实现对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();
}

答案 3 :(得分:5)

如果你想记录错误等,你应该使用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; 
}

答案 4 :(得分:2)

在阐述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失败时,我们就会出现错误。您还可以注意到,我们现在不需要将写入查询的状态存储到$result变量中进行验证,因为我们的函数现在自己处理它。与处理选择的方式相同,它只是像普通函数一样将结果赋值给变量,但是处理自身内部的错误。

另请注意,我们不需要显示实际错误,因为它们承担着巨大的安全风险,特别是对于这个过时的扩展。这就是为什么我们的默认设置在大多数情况下都会很好。但是,如果我们确实想要通知用户某些特定的查询错误,我们总是可以传递第二个参数来显示我们的自定义错误消息。

答案 5 :(得分:2)

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

我不确定是否有mysql版本,但添加这行代码允许抛出mysqli_sql_exception。
我知道,经过很多时间,问题已经检查过,但我得到了不同的答案,可能会有所帮助。

答案 6 :(得分:0)

    $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 :(得分:0)

DECLARE @Command NVARCHAR(MAX)= 'SELECT * FROM Product  WHERE ID = 12'
DECLARE @CountCommand NVARCHAR(MAX)= 'SELECT @Count=count(1) FROM Product  WHERE ID = 12'
DECLARE @Count AS INT
EXEC sp_executesql @CountCommand , N'@Count INT OUTPUT', @Count=@Count OUTPUT
  IF (@Count > 0)
   BEGIN
    EXECUTE (@Command)
   END
  ELSE
   BEGIN
    DECLARE @CatalogProduct VARCHAR(MAX) = 'SELECT p.ManufactureCode,p.PartNo,p.Size,p.ID AS ProductID,p.Name ,p.ParentProductID,p.BasePrice FROM Product.Product p WHERE p.ThruDate > GETDATE() '+@Where
            EXECUTE (@CatalogProduct)
   END
END

如果发生错误,您将得到类似这样的信息->

$new_user = new User($user);
$mapper = $this->spot->mapper("App\User");

try{
    $id = $mapper->save($new_user);     
}catch(Exception $exception){

    $data["error"] = true;
    $data["message"] = "Error while insertion. Erron in the query";
    $data["data"] = $exception->getMessage();

    return $response->withStatus(409)
    ->withHeader("Content-Type", "application/json")
    ->write(json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT));        
}

,状态码:409。

答案 8 :(得分:-1)

使用上一篇文章中描述的任何方法以某种方式捕获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) { .... }无效!

注意:与您的问题没有直接关系,但我认为如果您向用户展示有用的内容会更好。我永远不会重新访问一个只显示空白屏幕或任何神秘错误消息的网站。