Я использую PDO для перезаписи интерфейса веб-сайта для базы данных. Я использовал расширение mysql, но я никогда не беспокоился об обработке ошибок, и несколько обработчиков ошибок, которые у меня были, были в основном копированием.
Теперь я хотел бы сделать это правильно. Однако у меня возникают проблемы с поиском ошибок, как мне хотелось бы (такие ошибки, как «Duplicate Entry», «Null Value» и т. Д. В MySQL). Сколько из моего заявления должно быть в блоке try? Должно ли все это быть там? Я использую Include()
для подключения к моей базе данных (которая имеет собственную обработку ошибок), так что это только выполнение запроса, в котором есть ошибки в этом коде. Я не могу понять, почему он не обнаруживает ошибку при выполнении следующего кода:
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"
, но вместо этого следует сообщение об успешном завершении. (При попытке добавить двух пользователей «Джон»). Я проверил в PHPMyAdmin; индекс уникален и делает ошибку, как ожидалось, просто не используя этот код.
Вы должны посмотреть документацию. Но если вы ничего не найдете, вы можете добавить еще один улов:
<?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-плагинов получаются из собственного класса PHP Exception. (С 5,0, если у меня хорошая память).
Вопросы об исключении 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 уже есть встроенный).
Однако у меня возникают проблемы с поиском ошибок, как мне хотелось бы (такие ошибки, как «Duplicate Entry», «Null Value» и т. Д. В 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, ie duplicate name } else { throw $e; } }
и, конечно (как выяснилось, это проблема для этого вопроса), вам нужно настроить PDO в режиме исключения, либо в параметре конструктора, просто добавив код
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
сразу после подключения.