PHP单例数据库连接模式 [英] PHP singleton database connection pattern

查看:35
本文介绍了PHP单例数据库连接模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在使用 PHP 和 MySQL 进行一个小项目.我已经阅读了很多有关管理连接等的最佳做法的资料.

I've been working on a small project using PHP and MySQL. I've read a lot around about best practices on managing a connection and so on.

我还实现了(遵循周围的一些帖子)一个单例类来管理 MySQL 连接.

I've also implemented (following some posts found around) a singleton class to manage MySQL connections.

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;
        }
    }
}

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

But... If my website has like 10K visitors contemporaneously and I'm calling every time my singleton object, should I expect to have performance issues? I meant, shouldn't I have a kind of pool of connections instead of a singleton?

推荐答案

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

Using singletons in PHP is considered bad practice. From my experience the most problematic issue with them are unit tests. It is hard to ensure that two tests are independent when testing singletons.

我会将约束只应存在一个实例"的责任委托给创建 Db 对象的代码.

I would delegate the responsibility for the constraint "only one instance should exists" to the code which creates the Db object.

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

Also for me it looks like there is a misunderstanding in how Singletons work in PHP in contrast to other languages: If you have 10.000 concurrent requests for example, then each request runs in a separate PHP process or thread, meaning they will all have their own instance of the "singleton", there is no sharing of this object for more than a single request (when running PHP in common web backend scenarios)

PHP 中没有连接池",但是您可以使用 mysqli 持久连接来实现 mysql.可以通过在创建mysqli时在主机名前面传递p:来实现.这在这里可能会有所帮助,但要小心处理(意思是先阅读文档)

There is no "connection pooling" in PHP, but you can use mysqli persistent connections for mysql. It can be achieved by passing the p: in front of the hostname when creating mysqli. This might help here, but handle it with care (meaning read the documentation first)

然而,只是为了理论上,PHP 中的单例必须知道有人可以使用 clone 的事实.这意味着在您的情况下可以这样做:

However, just for theory, a singleton in PHP must be aware of the fact that someone could use clone. Meaning in your case it would be possible to do that:

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

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

To avoid that you can implement the __clone() method like this:

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

这篇关于PHP单例数据库连接模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆