php PHP单例数据库连接模式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21832809/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PHP singleton database connection pattern
提问by LucasM
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.
我一直在使用 PHP 和 MySQL 进行一个小项目。我已经阅读了很多关于管理连接等的最佳实践。
I've also implemented (following some posts found around) a singleton class to manage MySQL connections.
我还实现了(遵循周围的一些帖子)一个单例类来管理 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;
}
}
}
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?
但是...如果我的网站同时有大约 10K 访问者并且我每次都调用我的单例对象,我应该期望有性能问题吗?我的意思是,我不应该有一种连接池而不是单例吗?
回答by hek2mgl
Using singletonsin 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.
singletons在 PHP 中使用被认为是不好的做法。根据我的经验,它们最有问题的问题是单元测试。在测试单例时,很难确保两个测试是独立的。
I would delegate the responsibility for the constraint "only one instance should exists" to the code which creates the Db object.
我会将约束“只应存在一个实例”的责任委托给创建 Db 对象的代码。
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 中的工作方式似乎存在误解:例如,如果您有 10.000 个并发请求,那么每个请求都在单独的 PHP 进程或线程中运行,这意味着它们都有自己的“singleton”的实例,对于一个以上的请求,没有共享此对象(在常见的 Web 后端场景中运行 PHP 时)
There is no "connection pooling" in PHP, but you can use mysqlipersistent 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 中没有“连接池”,但您可以mysqli对 mysql使用持久连接。可以通过p:在创建 mysqli 时在主机名前面传递 来实现。这在这里可能会有所帮助,但要小心处理(意思是先阅读文档)
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:
然而,只是为了理论上,PHP 中的单例必须意识到有人可以使用clone. 这意味着在您的情况下可以这样做:
$db = DB::getInstance();
$db2 = clone $db;
To avoid that you can implement the __clone()method like this:
为避免这种情况,您可以实现如下__clone()方法:
public function __clone() {
throw new Exception("Can't clone a singleton");
}

