24

PDOを使用して、データベースのWebサイトインターフェイスを書き直しています。以前はmysql拡張機能を使用していましたが、エラー処理に煩わされることはなく、基本的にコピーアンドペーストであったエラーハンドラーもいくつかありました。

今、私はこれを正しくやりたいと思います。しかし、私が望む方法でエラーをキャッチするのに問題があります(MySQLの「重複エントリ」、「ヌル値」などのエラー)。私のステートメントのどのくらいがtryブロックにある必要がありますか?すべてがそこにあるべきですか?を使用Include()してDB(独自のエラー処理があります)に接続しているため、このコードでエラーが発生するのはクエリの実行のみです。次のコードを実行したときにエラーが発生しない理由がわかりません。

try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "The user could not be added.<br>".$e->getMessage();
}

だから私の質問:それはすべてtryブロックにある必要がありますか?実行をtryブロックに入れることはできますか?エラーをキャッチする必要がありますDuplicate value "John" in key "name"が、代わりに成功メッセージが表示されます。(2人の「ジョン」ユーザーを追加しようとした場合)。PHPMyAdminにチェックインしました。インデックスは一意であり、このコードを使用しないだけで、期待どおりにエラーがスローされます。

4

5 に答える 5

20

ドキュメントを確認する必要があります。しかし、何も見つからない場合は、別のキャッチを追加できます:

<?php
try {
  $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer)    VALUES (NULL, :name, :password, :question, :answer)");
  $stmt->bindValue(":name", $_POST['name']);
  $stmt->bindValue(":password", $_POST['password']);
  $stmt->bindValue(":question", $_POST['question']);
  $stmt->bindValue(":answer", $_POST['answer']);
  $stmt->execute();
  echo "Successfully added the new user " . $_POST['name'];
} catch (PDOException $e) {
  echo "DataBase Error: The user could not be added.<br>".$e->getMessage();
} catch (Exception $e) {
  echo "General Error: The user could not be added.<br>".$e->getMessage();
}
?>

PHPプラグインのすべての例外は、ExceptionネイティブPHPクラスから継承されるため、これは機能する必要があります。(私の記憶が良ければ5.0以降)。

于 2012-06-19T14:20:35.510 に答える
15

PDO例外の質問-それらをキャッチする方法

原則として -

それらを捕まえないでください

たとえば、ここでのコードはこのように記述する必要があります

$stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)");
$stmt->bindValue(":name", $_POST['name']);
$stmt->bindValue(":password", $_POST['password']);
$stmt->bindValue(":question", $_POST['question']);
$stmt->bindValue(":answer", $_POST['answer']);
$stmt->execute();
echo "Successfully added the new user " . $_POST['name'];

試行またはキャッチコールなしで。ここでは例外を処理するための特定のシナリオがないためです(単純なエコーが処理シナリオとしてカウントされることはほとんどありません)。

代わりに、アプリケーション全体のエラーハンドラーにバブルアップさせてください(この用語に怖がらないでください。PHPにはすでに組み込みのエラーハンドラーがあります)。

しかし、私が望む方法でエラーをキャッチするのに問題があります(MySQLの「重複エントリ」、「ヌル値」などのエラー)。

特定のシナリオがある場合にのみ、try-catch演算子を使用する必要がありますが、発生したエラーが予期したものであるかどうかを常に確認する必要があります。それ以外の場合は、例外を再スローする必要があります。

try {
    $pdo->prepare("INSERT INTO users VALUES (NULL,?,?,?,?)")->execute($data);
} catch (PDOException $e) {
    if ($e->getCode() == 1062) {
        // Take some action if there is a key constraint violation, i.e. duplicate name
    } else {
        throw $e;
    }
}

そしてもちろん(この質問の重大な問題であることが判明したため)、コードを追加するだけのコンストラクターパラメーターで例外モードでPDOを設定する必要があります

$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

接続直後。

于 2016-05-05T15:12:03.997 に答える
0

新しいPDO接続を行ったときにエラーを正しくスローする

       try{  try{
            $this->pdo = new \PDO($this->dsn,$this->options);
            $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
            //Display PDO Errors
            $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);



        }catch (\PDOException $e) {

            throw new CustomException ($e->getMessage());
        }

    }catch (CustomException $e)
    {

        $e->render();
    }
于 2021-10-01T13:53:01.447 に答える
0

あなたができることは、重複エントリのようなものからエラーコードをキャプチャし、次にif(str_contains($e, '1062 Duplicate entry')) {あなたの内部のようなものを使用することですcatch (PDOException $e) {

于 2021-10-15T11:51:20.627 に答える
-3
<?php
    $stmt = $db->prepare("INSERT INTO tbl_user (id, name, password, question, answer) VALUES (NULL, :name, :password, :question, :answer)");

    $stmt->bindValue(":name", $_POST['name']);
    $stmt->bindValue(":password", $_POST['password']);
    $stmt->bindValue(":question", $_POST['question']);
    $stmt->bindValue(":answer", $_POST['answer']);
    $inserted = $stmt->execute();

    if($inserted)
        echo "Successfully added the new user " . $_POST['name'];
    else
        echo "Somethig get wrong";
?>
于 2019-09-08T23:35:09.247 に答える