函数中的 PDO try-catch 用法
我正在考虑在我未来的所有 web 应用程序中使用 PDO.目前(使用到目前为止我从 SO 中学到的知识),我在我的站点中处理数据库连接的是一个像这样的 Singleton 类:
I'm thinking of using PDO in all of my future webapp. Currently (using what I've learned from SO so far), what I have in my site to handle database connection is a Singleton class like this :
class DB {
private static $instance = NULL;
private static $dsn = "mysql:host=localhost;dbname=mydatabase;";
private static $db_user = 'root';
private static $db_pass = '0O0ooIl1';
private function __construct()
{
}
private function __clone()
{
}
public static function getInstance() {
if (!self::$instance)
{
self::$instance = new PDO(self::$dsn, self::$db_user, self::$db_pass);
self::$instance-> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instance;
}
}
和另一个文件 (functions.php) 与内容特定的函数看起来完全一样:
and another file (functions.php) with content-specific functions looking exactly like this one :
function get_recent_activities ()
{
try
{
$db = DB::getInstance();
// --prepare and execute query here, fetch the result--
return $my_list_of_recent_activities;
}
catch (PDOException $e)
{
return "some fail-messages";
}
}
...
意味着我必须在所有函数中重复 try .. catch
部分.
meaning that I have to repeat the try .. catch
part in all of the functions.
我的问题是:
- 我应该如何提高效率?(例如,不必在所有函数中重复
try..catch
,但仍然能够在每个函数上返回不同的失败消息") - 这已经是一个好习惯了吗?我还是 PDO 和 OOP 的新手(还有很多东西要学习),所以(截至目前),我真的看不出有什么缺点或可以改进的地方.
- How should I make that more efficient ? (eg. not having to repeat
try..catch
in all functions, and yet still able to return different "fail-message" on each one) - Is this already a good practice ? I'm still new at PDO and OOP (still a lot more to learn), so (as of now), I can't really see any disadvantages or things that can be improved in there.
如果这看起来不清楚或太长,我很抱歉.提前致谢.
I'm sorry if that seems unclear or too long. Thanks in advance.
推荐答案
你的实现很好,而且在大多数情况下都能很好地工作.
Your implementation is just fine, and it'll work perfectly well for most purposes.
没有必要将每个查询都放在 try/catch 块中,事实上,在大多数情况下,您实际上并不想这样做.这样做的原因是,如果查询生成异常,则是语法错误或数据库问题等致命问题的结果,而这些不是您在执行每个查询时都应该考虑的问题.
It's not necessary to put every query inside a try/catch block, and in fact in most cases you actually don't want to. The reason for this is that if a query generates an exception, it's the result of a fatal problem like a syntax error or a database issue, and those are not issues that you should be accounting for with every query that you do.
例如:
try {
$rs = $db->prepare('SELECT * FROM foo');
$rs->execute();
$foo = $rs->fetchAll();
} catch (Exception $e) {
die("Oh noes! There's an error in the query!");
}
这里的查询要么正常工作,要么根本不工作.它根本不起作用的情况在生产系统上不应该有规律地发生,所以它们不是您应该在这里检查的条件.这样做实际上适得其反,因为您的用户会收到永远不会改变的错误,而您不会收到提醒您问题的异常消息.
The query here will either work properly or not work at all. The circumstances where it wouldn't work at all should not ever occur with any regularity on a production system, so they're not conditions that you should check for here. Doing so is actually counterproductive, because your users get an error that will never change, and you don't get an exception message that would alert you to the problem.
相反,只需这样写:
$rs = $db->prepare('SELECT * FROM foo');
$rs->execute();
$foo = $rs->fetchAll();
一般来说,您唯一需要捕获和处理查询异常的时间是在查询失败时您想执行其他操作的时候.例如:
In general, the only time that you'll want to catch and handle a query exception is when you want to do something else if the query fails. For example:
// We're handling a file upload here.
try {
$rs = $db->prepare('INSERT INTO files (fileID, filename) VALUES (?, ?)');
$rs->execute(array(1234, '/var/tmp/file1234.txt'));
} catch (Exception $e) {
unlink('/var/tmp/file1234.txt');
throw $e;
}
您需要编写一个简单的异常处理程序,用于记录或通知您生产环境中发生的数据库错误,并向您的用户显示友好的错误消息而不是异常跟踪.请参阅 http://www.php.net/set-exception-handler 了解有关怎么做.
You'll want to write a simple exception handler that logs or notifies you of database errors that occur in your production environment and displays a friendly error message to your users instead of the exception trace. See http://www.php.net/set-exception-handler for information on how to do that.
相关文章