PHP单例数据库连接模式

标签 php mysql mysqli singleton

我一直在使用 PHP 和 MySQL 开发一个小项目。我已经阅读了很多关于管理连接等方面的最佳实践。

我还实现了(根据周围发现的一些帖子)一个单例类来管理 MySQL 连接。

require_once 'config.inc.php';
class DbConn {

    private static $instance;
    private $dbConn;

    private function __construct() {}

    /**
     *
     * @return DbConn
     */
    private static function getInstance(){
        if (self::$instance == null){
            $className = __CLASS__;
            self::$instance = new $className;
        }

        return self::$instance;
    }

    /**
     *
     * @return DbConn
     */
    private static function initConnection(){
        $db = self::getInstance();
        $connConf = getConfigData();
        $db->dbConn = new mysqli($connConf['db_host'], $connConf['db_user'], $connConf['db_pwd'],$connConf['db_name']);
        $db->dbConn->set_charset('utf8');
        return $db;
    }

    /**
     * @return mysqli
     */
    public static function getDbConn() {
        try {
            $db = self::initConnection();
            return $db->dbConn;
        } catch (Exception $ex) {
            echo "I was unable to open a connection to the database. " . $ex->getMessage();
            return null;
        }
    }
}

但是...如果我的网站同时有大约 10,000 名访问者,并且我每次都调用我的单例对象,我是否应该预期会出现性能问题?我的意思是,我不应该有一种连接池而不是单例吗?

最佳答案

在 PHP 中使用 singletons 被认为是不好的做法。根据我的经验,他们最有问题的问题是单元测试。测试单例时很难保证两个测试是独立的。

我会将“只有一个实例应该存在”这一约束的责任委托(delegate)给创建 Db 对象的代码。

另外对我来说,与其他语言相比,单例在 PHP 中的工作方式似乎存在误解:例如,如果您有 10.000 个并发请求,那么每个请求都在单独的 PHP 进程或线程中运行,这意味着它们都将有自己的“单例”实例,对于多个请求不共享此对象(在常见的 Web 后端场景中运行 PHP 时)

PHP 中没有“连接池”,但是可以使用mysqli 持久连接来连接mysql。可以通过在创建mysqli时在主机名前面传递p:来实现。这可能在这里有所帮助,但要小心处理 ( meaning read the documentation first )


然而,仅就理论上而言,PHP 中的单例必须意识到有人可以使用 clone 这一事实。在您的情况下,这意味着可以这样做:

$db = DB::getInstance();
$db2 = clone $db; 

要避免这种情况,您可以像这样实现 __clone() 方法:

public function __clone() {
    throw new Exception("Can't clone a singleton");
}

关于PHP单例数据库连接模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21832809/

相关文章:

php - 选择多行 PHP/MySQL

mysql - 如何防止在数据库中手动编辑数据?

php - 如何从数据库中获取逗号分隔值

php - MySQL,longtext、text 或 blob 哪个更高效?提高插入效率

php - 创建一个动态的单页 Web 应用程序

php - 使用 join 列出 mysql 中的结果

php - 刷新 jquery ajax 响应中的特定元素

php - SQL 更新、设置、案例 : What am I doing wrong?

php - 优化我的 Mysql 查询以获取库存状态

mysql - MySQL 过程中的多个 IF 语句