问题描述
我正在考虑在以后的所有Web应用程序中使用PDO.当前(使用到目前为止的经验教训),我站点中用于处理数据库连接的内容是一个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.
相反,只需编写以下内容:
Instead, just write this:
$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.
这篇关于PDO try-catch在函数中的用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!