web-dev-qa-db-ja.com

MySQLiでクエリエラーを例外に変える

MySQLiクエリエラーを例外に変えようとしていますが、できませんでした-- mysqli_sql_exception は、DBへの接続に失敗した場合にのみスローされます。

mysqli_report(MYSQLI_REPORT_STRICT)とカスタムラッパークラスに埋め込まれた手続き型MySQLi関数を使用しました。

以前のコード:

public function mysqlQuery($SQL) {

    $this->Result = mysqli_query($this->DBlink, $SQL);

    if($this->Result === false)
        throw new MySQLiQueryException($SQL, mysqli_error($this->DBlink), mysqli_errno($this->DBlink));

    return $this->Result;

}

質問:クエリが失敗したときに警告も例外もスローされないので、mysqli_query()がfalseを返したかどうかを確認する必要がありますか?

22
Roman Newaza

少し前に、私はなんとかこの問題を整理することができました。 その他の回答 で指摘されたように、

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

mysqliに例外をスローするように指示する正しい方法です。

すべてのクエリをtry-catchでラップしないように注意してください。これは非常に一般的な誤解であり、例外の使用を開始するとすぐに、試行をスローし始め、左右にキャッチする必要があります。まったく逆に、try-catchは慎重に使用する必要があります。エラーの99%は適切に処理されるべきではなく、サイト全体のエラーハンドラーによって処理されるべきです。 PHPエラー報告 に関する私の記事からこのトピックについてもっと読むことができます

27

mysqli_query()がfalseを返したかどうかを確認する必要がありますか?

番号。

必要なことを実行し、SQLエラーで例外をスローするようにmysqliドライバーに指示できるはずですが、まだ有効になっていない場合は_MYSQLI_REPORT_ERROR_を有効にする必要があります。

_mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT)
_

mysqli_query()はエラー時に例外をスローするはずです。戻り値の失敗をチェックする必要はありません(例外がスローされるため、とにかく発生しません)。

_public function mysqlQuery($SQL) {
    try {
        $this->Result = mysqli_query($this->DBlink, $SQL);
    } catch (mysqli_sql_exception $e) {
        throw new MySQLiQueryException($SQL, $e->getMessage(), $e->getCode());
    }
    return $this->Result;
}
_

(注:再スローされた例外で_$this->SQL_を_$SQL_に変更しました。)

24
MrWhite

少し手遅れだとは思いますが、後世のためです。 MYSQLI_REPORT_STRICTは制限的であり、特定の例外が発生しないため、catchブロックで処理できませんでした。

 mysqli_report(MYSQLI_REPORT_ALL); // Traps all mysqli error 

 try {
    $mysqli = new mysqli('localhost','user,'pwd','db');

     /* I don't need to explicitly throw an exception as this is being
      done automatically */

 } catch(Exception $e) {
    echo $e->getMessage();
 }  
1
kodepet