20

PDO プリペアド ステートメントを使用して、MySQL データベースでクエリの適切なエラー処理を作成しようとしています。プリペアド ステートメントの処理でエラーが検出された時点でプログラムを終了させたい。PDO のプリペアド ステートメント プロセスの各ステップがFalse失敗すると返されるという事実を利用して、私は次の不快なハックをまとめました。

 global $allFields;
 global $db;
 global $app;
 //dynamically append all relevant fields to query using $allFields global
 $selectQuery = 'SELECT ' . implode($allFields, ', ') .
     ' FROM People WHERE ' . $fieldName . ' = :value';
 //prepared statement -- returns boolean false if failure running query; run success check
 $success = $selectQueryResult = $db->prepare($selectQuery);
     checkSuccess($success);
 $success = $selectQueryResult->bindParam(':value', $fieldValue, PDO::PARAM_STR);
     checkSuccess($success);
 $success = $selectQueryResult->execute();
     checkSuccess($success);

次のことをcheckSuccess()行うと:

function checkSuccess($success) {
    if ($success == false) {
        //TODO: custom error page. 
        echo "Error connecting to database with this query.";
        die();
    }
}

2つのこと。まず、これは恐ろしく冗長で愚かです。もっと良い方法があるはずです。明らかに、ブール値を配列または何かに格納して、1行または2行のコードを取り出すことができますが、それでも.

2 つ目は、これらの値を確認する必要があるのか​​、それとも次のコード行を実行した後に結果を確認する必要があるのか​​ということです。

$result = $selectQueryResult->fetch(PDO::FETCH_ASSOC);

私はすでにこれを行うコードを持っています:

if ($result) { //test if query generated results
    // do successful shit
}

else {
    echo "404";
    $app->response()->status(404); //create 404 response header if no results

奇妙な、不一致の、または長いクエリを挿入して、プリペアドステートメントプロセスを中断しようとする限り、私のプログラムは、実行した関数のいずれに$resultも戻ることなく、常に割り当てに到達します。では、上記のロジックをまったくチェックする必要はないのでしょうか? プログラムの早い段階で、データベース接続が成功したかどうかを確認していることを覚えておいてください。falsecheckSuccess()

4

2 に答える 2

25

エラーモードを次のような例外をスローするように設定することをお勧めします。

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

データベースに接続した直後。したがって、すべての問題で PDOException がスローされるため、コードは次のようになります。

$selectQuery = '
                SELECT 
                    ' . implode($allFields, ', ') . ' 
                FROM 
                    People 
                WHERE 
                    ' . $fieldName . ' = :value
';
try
{ 
    $selectQueryResult = $db->prepare($selectQuery);
    selectQueryResult->bindParam(':value', $fieldValue);
    $selectQueryResult->execute();
}
catch(PDOException $e)
{
    handle_sql_errors($selectQuery, $e->getMessage());
}

関数は次のようになります。

function handle_sql_errors($query, $error_message)
{
    echo '<pre>';
    echo $query;
    echo '</pre>';
    echo $error_message;
    die;
}

実際、私は次のようなものも持つ一般的な関数を使用しています

$debug = debug_backtrace();
echo 'Found in ' . $debug[0]['file'] . ' on line ' . $debug[0]['line'];

複数のクエリを実行している場合、どこに問題があるかを教えてください

于 2013-03-07T16:00:07.460 に答える
6

キャッチする必要がありますPDOException

try {
    //your code/query
} catch (PDOException $e) {
    //Do your error handling here
    $message = $e->getMessage();
}

PDOException

于 2013-03-07T15:56:57.777 に答える