问题描述
我当前正在使用MySQLi准备的语句来进行数据库处理.因为MySQLi准备好的语句仅在连接错误时才抛出错误,所以我不得不自己检查错误并自己抛出错误.在PDO中(我将在以后使用它,因为我确信现在它会更好地工作),因为PDO确实会引发预期的错误,您可以使用PDOException捕获错误,所以错误处理的可能性要大得多.
I am currently using MySQLi prepared statements for my database handling.Because MySQLi prepared statements only throw an error when the connection is wrong, I am forced to check for errors myself and to throw them myself too.In PDO (which I am going to use in the future because I'm convinced now it works way better) there is a much better error handling possible because PDO does throw errors as expected which you can catch with PDOException.
但是,到目前为止,我仍然使用MySQLi,所以我想知道我当前的代码是否是好的做法?在许多教程和书籍中,我可以找到类似的工作流程,但是在某些地方,我读到使用异常通知用户某些方法失败是低效的,被认为是不正确的做法." ( http://www.sitepoint.com/forums/showthread.php?872057-should-i-use-1-or-many-try-catches-in-a-page-that -uses-PDO )
But for now, I am stuck with MySQLi, so I want to know if my current code is good practice?In a lot of tutorials and books I can find a similar workflow however at some places I read "Using exceptions to notify the user that some method failed is inefficient and considered bad practice." (http://www.sitepoint.com/forums/showthread.php?872057-should-i-use-1-or-many-try-catches-in-a-page-that-uses-PDO)
try{
$user = $dataUser->getById(1);
}catch(UserNotFoundException $unfe){
echo 'No user found with the provided id';
}catch(Exception $exc){
//do some logging with the real exception
...
//show a readable error to the website visitor
echo "There was an error retrieving the user from the database.";
}
In my function I use something like this:
function getById($id){
$query = "select user_id, username,firstname from users where user_id = ?";
if ($stmt = $this->database->getConnection()->prepare($query)) {
$stmt->bind_param('i',$id);
if($stmt->execute()){
throw new exception('There was an error retrieving the user by id: ' . $stmt->error);
}
$stmt->bind_result($userId,$username);
$stmt->store_result();
$stmt->fetch();
if(($stmt->num_rows) == 1){
$stmt->close();
$user = new User($username);
$user->userId = $userId;
$user->username = $username;
return $user;
}else{
$stmt->close();
throw new UserNotFoundException("No user found matching the id.");
}
}else{
throw new Exception("There was a database error retrieving the user by id: " . $this->database->getConnection()->error);
}
}
更新1 基于您的常识"的注释
UPDATE 1 based on the comment of 'Your Common Sense'
mysqli_report(MYSQLI_REPORT_ALL);
效果不佳..
我已经做了一些练习,但是我仍然不清楚异常和错误之间到底有什么区别.使用PDO时,执行失败时会引发异常. Mysqli没有.您必须自己检查它,然后扔掉它.假设我使用了一个数据库包装程序,并将其命名为:
I have done some practice but it is still not clear to me what exactly is the difference between exceptions and errors.When I use PDO, I throws exceptions when the execute fails. Mysqli doesn't.You have to check it yourself and than throw it.Let's say I use a databasewrapper and call it:
$this->db->getOne($query,'id');
在此方法中的某处出现$ stmt-> execute.我应该检查它是否成功并引发异常,还是应该在这里触发错误?
Somewhere in this method $stmt->execute appears. Should I check if it succeeded and throw an exception or should I trigger an error here?
因为您建议使用error_handler.
Because you are suggesting an error_handler.
这让我感到困惑,因为如果我使用pdo,应该使用exception_handler对吗?
Its confusing to me because if I use pdo, I should use an exception_handler right?
更新2
-
ajax呢?我使用JSON返回结果.如果发生错误,我应该在这里使用try catch返回json.success是true还是false?还是我应该在这里处理错误?
What about ajax? I use JSON to return results. In case of an error, should I use try catch here to return json.success true or false? Or how should I handle errors here?
如果我想显示更多具体信息怎么办?例如:当用户执行注册并使用已经准备好注册的用户名和/或电子邮件时,由于违反了唯一密钥,将引发错误.但是我不仅要显示嘿,发生500错误",因为在这种情况下,重要的是注册者必须知道问题所在,例如使用此用户名",...
What if I want to show more specific information?For example: when a user performs a registration and uses a username and/or e-mail that is allready registered, an error is thrown because the unique key is violated.But I don't just want to show "hey a 500 error occured", because in this case, it is important that the registrator knows whats the problem, like "this username is taken", ...
在这种情况下,尝试捕获是一种好习惯,因为您想显示详细的信息是正确的吗?
So is it correct that in these cases, a try catch is good practice because you want to show detailed information?
我只是在什么时候使用try catch和什么时候让全局错误处理程序为我处理错误感到困惑.在此主题中,我阅读了以下内容:
I'm just confused on when to use try catch and when to let the global error handler deal the error for me.In this topic I read this:
您可以使用set_exception_handler()处理自定义函数中未捕获的异常.但是,正确"的方法是让您尝试...在例如进行查询,然后使用您的自定义函数将其记录下来."但这在本主题中被认为是不良做法.
"You can use set_exception_handler() to deal with uncaught exceptions in your custom function.The "right" way, however, would be for you to try ... catch the exception when e.g. doing a query, and use your custom function to log it accordingly."But that is considered bad practice in this topic.
推荐答案
不.在许多方面.
首先,mysqli最终用此异常事件进行了管理.
First of all, mysqli managed at last with this exception thing.
mysqli_report(MYSQLI_REPORT_ALL);
会告诉mysqli抛出异常.
will tell mysqli throw exceptions. Yet,
完全正确.最后,一个足够聪明的人来应对所有这些无用的教程和书籍.
Exactly. At last someone smart enough to counter all these useless tutorials and books.
//do some logging with the real exception
对于应用程序中的每个查询,
相当...多余.你不觉得吗但是,
for the every query in your application is quite... redundant. Don't you think? Yet,
//show a readable error to the website visitor
不是那么可读".是的,这是简单的英语.但是,站点访问者与数据库有什么关系?什么用户?什么是检索"? 所有这些东西都是无用的和令人困惑的.请查看一些专业构建的网站,例如在这个网站上.他们不会给您增加任何技术细节的负担,仅显示通用的500错误页面.
is not that "readable". yes, it is plain English. But what a site visitor has to do with database? What user? What was "retrieving"? All this stuff is useless and confusing. Please take look ot some professionally-built sites, at this one for example. They don't burden you with any technical details, showing a generic 500 error page only.
并非必须对您在代码中执行的每个操作都进行此操作,而是必须使用set_error_handler()集中进行此操作.
And it has to be done not for the every operation you do in your code, but centralized, using set_error_handler().
虽然必须仅使用异常来处理错误本身.
While exceptions have to be used only to handle the error itself.
因此,您的try..catch块是完全多余的.如果发生错误,则必须由错误处理程序捕获异常,并记录错误并显示一般500错误页面.
So, your try..catch block is completely redundant. In case of error an exception have to be caught by error handler, error logged and generic 500 error page shown.
throw new exception('There was an error retrieving the user by id: ' . $stmt->error);
您难道找不到这段代码,被添加到每个查询执行中,又很多余吗?您真正需要的是一个数据库处理程序类来完成所有肮脏的工作.
Don't you find this piece of code, being added to the every query execution, a quite redundant again? What you really need is a database handler class to do all the dirty job.
查看此函数的外观:
function getById($id)
{
$query = "select username from users where user_id = ?";
$name = $this->db->getOne($query,$id);
return new User($name);
}
所有数据库操作的两行.
TWO rows for all the database operations.
(但是您创建User类的想法很奇怪)
(however your idea of creating User class is quite strange)
这篇关于在函数中引发异常或如何执行下降错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!