2008-09-06 9 views
10

私は、JobName列をUNIQUEとして定義するMySQLテーブルを扱っています。すでにデータベースにあるJobNameを使用して誰かが新しいJobをデータベースに保存しようとすると、MySQLは警告をスローします。PHPでMySQLの警告を検出して処理できますか?

PHPスクリプトでエラーと同様にこの警告を検出し、適切に処理したいと考えています。理想的には、MySQLがどのような警告をスローしたかを知りたいので、コードを分岐して処理することができます。

これは可能ですか?もしそうでなければ、MySQLはこの能力を持っていないか、PHPはこの能力を持っていないか、あるいはその両方ですか?

答えて

10

PHPに「フラグを立て」する警告がネイティブにこの質問の範囲を超えて明らかであるのmysql/mysqliのドライバへの変更を必要とするため。あなたは慎重にするときについて考える必要があるかもしれませんので、

$warningCountResult = mysql_query("SELECT @@warning_count"); 
if ($warningCountResult) { 
    $warningCount = mysql_fetch_row($warningCountResult); 
    if ($warningCount[0] > 0) { 
     //Have warnings 
     $warningDetailResult = mysql_query("SHOW WARNINGS"); 
     if ($warningDetailResult) { 
      while ($warning = mysql_fetch_assoc(warningDetailResult) { 
       //Process it 
      } 
     } 
    }//Else no warnings 
} 

は明らかにこれは、EN-質量適用する恐ろしく高価になるだろう。代わりに、基本的に、あなたが警告のデータベースに作るすべてのクエリをチェックする必要があるとしていますどのように警告が発生する可能性がありますか(リファクタリングで消滅させる可能性があります)。参考のため

、もちろんMySQL SHOW WARNINGS

、あなたはあなたの実行ごとにクエリを保存するだろうSELECT @@warning_count、のための最初のクエリで済ますことができますが、私は知識をひけらかす完全性のためにそれを含めます。

+0

また、warning_countプロパティを持つMySQLiドライバを使用してください。 http://php.net/manual/en/mysqli.warning-count.php –

4

まず、turn warnings offにアクセスして、訪問者にあなたのというエラーが表示されないようにしてください。第2に、mysql_query()に電話をかけたときに、falseを返したかどうかを確認する必要があります。そうなった場合は、mysql_errno()に連絡して、何が問題になったのかを調べてください。 this pageのエラーコードに返された番号を一致させます。

それはこのようになります

は、あなたが探しているエラー番号です:私は今、あなたの状況には適用されません実現のerrno機能に関するものを取り除くために更新

Error: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)

Message: Can't write, because of unique constraint, to table '%s'

+5

私は誤解されていないと、彼は警告ではなくエラーについて質問しています。警告は依然としてクエリが通過することを許し、したがって 'mysql_query'は' false'を返しません。 PHPの限られた警告のサポートについては、iAnの答えを参照してください。 – Andrew

0

...

UPDATEステートメントの場合、MySQLでは注意すべきことの1つは、WHERE句が一致する行があっても035を返しますが、SET句は実際にデータ値を変更しませんでした。私はこれが言及しているのは、その挙動が一度見たシステムのバグを引き起こしたからです。プログラマーは、更新後にエラーを確認するために戻り値を使用しました。これは単に、ユーザーが更新ボタンをクリックする前に既存の値を変更しなかったことを意味します。

mysqli_affected_rows()は、テーブルにupdate_time列のようなものがあり、更新時に常に新しいタイムスタンプ値が割り当てられていない限り、そのような警告を見つけるのに頼ることはできません。そのような回避策はちょっとしたものだ。

0

あなたが使用しているフレームワーク(もしあれば)によっては、あなた自身でジョブ名を確認し、フォームの残りの検証でユーザーに適切な情報を作成するクエリを実行することをお勧めします。

ジョブ名の数に応じて、フォームを含むビューに名前を送信し、javascriptを使用して、使用されていることを伝えることができます。

これがあなたにとって理にかなっていない場合は、私の見解を総括するといいでしょう。あなたのプログラムやユーザーが違法な行為を試み、エラーをキャッチして処理しないようにしないでください。エラーを作成しないようにシステムを設計する方がはるかに優れています。実際のバグにエラーをしてください:)

0

mysqli文のエラー番号を使用して、ユニークキー違反を検出できます。 mysqli文はER_DUP_ENTRYというエラー1062を返します。エラー1062を探し、適切なエラーメッセージを出力することができます。エラーメッセージの一部として列(jobName)を印刷する場合は、文のエラー文字列を解析する必要があります。

 
    if($stmt = $mysqli->prepare($sql)){ 
      $stmt->bind_param("sss", 
      $name, 
      $identKey, 
      $domain); 


      $stmt->execute(); 
      if($mysqli->affected_rows != 1) { 
         //This will return errorno 1062 
       trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR); 
       exit(1); 
      } 
      $stmt->close(); 
     } else { 

      trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR); 
     } 
0

mysqliではmysqlよりも警告をより効率的に取得できます。ここで

コードが財産mysqli-> warning_countためphp.netに手動pageに示唆している:警告を抑制する上

$mysqli->query($query); 

if ($mysqli->warning_count) { 
    if ($result = $mysqli->query("SHOW WARNINGS")) { 
     $row = $result->fetch_row(); 
     printf("%s (%d): %s\n", $row[0], $row[1], $row[2]); 
     $result->close(); 
    } 
} 
0

注:一般的に、あることから警告を防ぐために、良いアイデアではありませんあなたが何か重要なことを見逃しているかもしれないので、なんらかの理由で警告を非表示にする必要がある場合は、文の前に@記号を付けることで個別に行うことができます。そうすれば、すべての警告レポートをオフにする必要はなく、特定のインスタンスに限定することができます。

例:

// this suppresses warnings that might result if there is no field titled "field" in the result 
$field_value = @mysql_result($result, 0, "field"); 
+1

ユーザーは、エラーをキャッチして、それを抑圧したくないように思えます。 – pgreen2

+0

'ini_set( 'display_errors'、0);'を使用する方が良いでしょう(php.iniに入れておく方が良い)、セキュリティリスクを引き起こす可能性のあるものは見えません。それと並行して、 'error_log'が書き込み可能なファイルに設定されていることを確認し、' error_reporting = -1'を設定することで潜在的な問題がすべて分かるようにします。 –

3
ini_set('mysql.trace_mode', 1) 

あなたが探しているものかもしれません。

PHPのエラーはカスタムPHPエラーハンドラで処理できますが、通常はログファイルに記録されているようにphpエラーを表示するのをオフにすることもできます(PHPの設定によって異なります)。

関連する問題