我正考虑在未来的所有webapp中使用PDO.目前(使用我迄今为止从SO中学到的东西),我在我的网站中处理数据库连接的是一个Singleton类,如下所示:
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)看起来完全像这样:
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
在所有功能中重复该部分.
我的问题是:
我应该如何提高效率?(例如,不必try..catch
在所有功能中重复,但仍然能够在每个功能上返回不同的"失败消息")
这已经是一个好习惯吗?我仍然是PDO和OOP的新手(还有很多东西需要学习),所以(截至目前),我无法真正看到任何可以在那里改进的缺点或事物.
如果这看起来不清楚或太长,我很抱歉.提前致谢.
你的实现很好,它对大多数用途都能很好地工作.
没有必要将每个查询都放在try/catch块中,事实上在大多数情况下你实际上并不想这样做.这样做的原因是,如果查询生成异常,则会出现诸如语法错误或数据库问题等致命问题,并且这些问题不是您应该对每个查询执行的问题.
例如:
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!"); }
这里的查询将正常工作或根本不工作.它根本不起作用的情况不应该在生产系统上有任何规律性,因此它们不是你应该在这里检查的条件.这样做实际上会适得其反,因为您的用户会收到永远不会改变的错误,并且您不会收到提醒您解决问题的异常消息.
相反,只需写下:
$rs = $db->prepare('SELECT * FROM foo'); $rs->execute(); $foo = $rs->fetchAll();
通常,您唯一想要捕获和处理查询异常的时间是在查询失败时要执行其他操作的时间.例如:
// 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.