28

PHPを使用してデータベースを使用するには、次のスクリプトを使用しています。

try{
    $db = new PDO('mysql:host='.$host.';port='.$port.';dbname='.$db, $user, $pass, $options);
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

ここで、このデータベースハンドルを使用して、次のコードを使用してリクエストを実行します。

try{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}

ここに問題があります:

  • DBへの接続に問題がなければ、すべてが機能します。
  • 接続が失敗したがDBを使用していない場合、$GLOBALS['errors'][]アレイがあり、スクリプトはその後も実行されます。
  • DBへの接続に失敗すると、次の致命的なエラーが発生します。

注意:未定義の変数:32行目のC:\ xampp \ htdocs [...]\test.phpのdb

致命的なエラー:32行目のC:\ xampp \ htdocs [...] \ test.phpの非オブジェクトでメンバー関数prepare()を呼び出す

注: 32行目が$query = $db->prepare(...)命令です。

つまり、スクリプトがクラッシュし、try/catchは役に立たないようです。この2回目の試行/キャッチが機能しない理由とその解決方法を知っていますか?

助けてくれてありがとう!

編集:いくつかの本当に良い返事があります。自分がやりたかったこととは正確に一致しないものを検証しましたが、おそらくこれが最善のアプローチです。

4

6 に答える 6

38

try/catchブロックは、スローされた例外に対してのみ機能します (throw ExceptionまたはのサブクラスをException呼び出す必要があります)。try/を使用して致命的なエラーをキャッチすることはできませんcatch

DB 接続を確立できない場合は、ページ上で意味のあることを行うために DB が必要になる可能性があるため、致命的であると考えます。

PDO接続を確立できない場合、例外がスローされます。あなたの特定の問題は、$dbそれを使用してメソッドを呼び出そうとしたときに定義されていないため、致命的なヌルポインター(一種)を取得することです。他の人が示唆しているようにフープを飛び越えるのではなくif ($db == null)、コードを修正して、$db必要なときに常に定義されるようにするか、DB 接続を使用するコードで DB 接続が利用可能であることを確認する脆弱性の低い方法を用意する必要があります。

致命的なエラーを本当に「キャッチ」したい場合は、 を使用しますset_error_handlerが、これでも致命的なエラーでスクリプトの実行が停止します。

于 2012-10-17T06:55:10.023 に答える
0

データベース接続が失敗した場合、$db最初のtry .. catchブロックから null になります。そのため、後で非オブジェクトのメンバーを使用することはできません$db->prepare(...)。この追加を使用する前に

if ($db) {
    // other try catch statement
}

これにより、db インスタンスを操作できるようになります。

于 2012-10-17T06:46:20.557 に答える
-1

次のifステートメントを追加してみてください。

if ($db) {
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(....);
}
else die('Connection lost');
于 2012-10-17T06:45:26.690 に答える
-1
try{
if(!is_null($db))
{
    $query = $db->prepare("INSERT INTO users (...) VALUES (...);");
    $query->execute(array(
        '...' => $...,
        '...' => $...
    ));
}
}
catch(Exception $e){
    $GLOBALS['errors'][] = $e;
}
于 2012-10-17T06:49:50.993 に答える