Подтвердить что ты не робот

Проверка ошибок для подготовленных заявлений PDO

Я пытаюсь создать правильную обработку ошибок для запросов в базе данных MySQL с помощью подготовленных инструкций PDO. Я хочу, чтобы программа вышла из того момента, когда обнаружена ошибка в подготовленном операторе. Воспользовавшись тем, что каждый шаг в процессе подготовки отчета 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 кода, но все же.

Во-вторых, даже необходимо проверить эти значения или просто проверить результат после выполнения этой строки кода:

$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 присваиванием без возврата False для любой из функций, в которых я запускаю checkSuccess(). Может, мне вообще не нужно проверять логику выше? Имейте в виду, что я проверял успешное соединение с базой данных ранее в программе.

4b9b3361

Ответ 1

Я предпочитаю, чтобы режим ошибки выдавал исключения следующим образом:

$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'];

чтобы сообщить мне, где была проблема, если я выполняю несколько запросов

Ответ 2

Вы должны поймать PDOException:

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

PDOException