web-dev-qa-db-ja.com

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);
...
23
meme

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
25
Yacoby

これはトリックを行うことができます、

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

独自に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();
}
8
Nemoden

エラーなどを記録したい場合、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
engvrdr

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変数に保存する必要がないことに注意してください。これは、関数がそれ自体で処理するためです。また、選択を処理するのと同じ方法で、通常の関数と同様に結果を変数に割り当てるだけで、エラー自体を処理します。

また、特にこの旧式の拡張機能では、実際のエラーが大きなセキュリティリスクを負うため、実際のエラーを表示する必要はありません。そのため、ほとんどの場合、デフォルトで十分です。ただし、特定のクエリエラーについてユーザーに通知する場合は、常に2番目のパラメーターを渡してカスタムエラーメッセージを表示できます。

3
Anonymous
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

これのmysqlバージョンがあるかどうかはわかりませんが、このコード行を追加するとmysqli_sql_exceptionをスローできます。
知っています、かなりの時間が経ち、質問の回答はすでにチェックされていますが、別の回答が得られ、役に立つかもしれません。

2
starkm
    $sql = "INSERT INTO   customer(FIELDS)VALUES(VALUES)";
    mysql_query($sql);
    if (mysql_errno())
    {
            echo "<script>alert('License already registered');location.replace('customerform.html');</script>";
    }   
0
Vishal
$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));        
}

エラーが発生した場合、次のようになります->

{
    "error": true,
    "message": "Error while insertion. Erron in the query",
    "data": "An exception occurred while executing 'INSERT INTO \"user\" (...) VALUES (...)' with params [...]:\n\nSQLSTATE[22P02]: Invalid text representation: 7 ERROR:  invalid input syntax for integer: \"default\"" }

ステータスコード:409。

0
Bharat Chhabra