doupu7651 2012-11-21 17:39
浏览 38
已采纳

以下代码如何确保每个浏览器只创建一个与数据库的连接?

I came across this piece of code that's supposed to ensure that only one database connection is created per browser so that the application sees improved performance due to the reduced number of calls to the database.

I believe I do understand the logic how this is ensured but I just need to confirm that my understanding on this is correct and complete. So, please help me with the explanation details.

Also is there a better practice than this when making database connection/calls ?

class Database {
    private static $dsn = 'mysql:host=localhost;dbname=mydatabase';
    private static $username = 'dbuser';
    private static $password = 'dbpass';
    private static $db;

    private function __construct() {}

    public static function getDB ()
    {
        if (!isset(self::$db)) {
            try {
                self::$db = new PDO(self::$dsn,
                                 self::$username,
                                 self::$password);
            } catch (PDOException $e) {
                $error_message = $e->getMessage();
                include('../errors/database_error.php');
                exit();
            }
        }
        return self::$db;
    }
}
  • 写回答

1条回答 默认 最新

  • dougan5772 2012-11-21 17:54
    关注

    As @raina77ow noted in a comment, this is called the Singleton pattern. Here's some explanation:

    The point of being a Singleton is that no calling code can create more than one $db. And to provide global access from anywhere in your code to the created $db.

    Static class variables exist as exactly one instance per class. Therefore you can't create multiple $db connections even if you could instantiate this class as an object.

    Since there's no purpose to instantiating the class as an object (that would only be useful if the class had non-static variables that existed per object instance), the class constructor is not needed. To prevent calling code from being tempted to call new, the constructor is made private. (Strictly speaking, there would be no harm in doing so, because the only class variables are static anyway.)

    Note that your implementation is missing the magic __clone and __wakeup methods. Without these your Singleton can still be cloned and unserialized. So technically, your Singleton is not enforcing singularity properly.

    Here are some additional thoughts:

    • Singleton classes (or any classes with static usage) are notoriously difficult to integrate into automated testing. Since they're static, you can initialize them once and they retain their state for the duration of your test suite. If you use non-static classes, you can re-initialize them each time you use new to instantiate a new object.

    • An alternative design is to use a Registry pattern, and some kind of bootstrap for your application that creates a non-static db instance and stores it in the registry.

    • If you do use Singleton, it's sometimes recommended to declare the Singleton class final so no subclasses can override the behavior or get access to the private data.

    • Your database credentials are hard-coded as private data in the class definition. I wouldn't do that. If your Apache PHP handler gets misconfigured, users could see your PHP source code, and then they'd have your database password. Put the database connection parameters into a config file, and store the config file outside your Apache document root.

    • Outputting the db connection error message verbatim can reveal information to users. Log the PDO error message, but put out a friendly message for users like "we're experiencing a problem, please notify the site administrator."

    • You don't need to terminate PHP blocks with ?> in a class definition file. It adds a risk that you could have a space or a newline after the close, which will become whitespace in your application and throw off your layout. Those types of errors are maddening to track down.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 python的qt5界面
  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100