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