我一直在使用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;
}
}
}
但是......如果我的网站同时拥有10K访问者,并且每次我的单身对象都会打电话,我是否应该有性能问题?我的意思是,我不应该有一种连接池而不是单身人士吗?
答案 0 :(得分:9)
在PHP中使用singletons
被认为是不好的做法。根据我的经验,最棘手的问题是单元测试。在测试单例时,很难确保两个测试是独立的。
我会将约束的责任“只存在一个实例”委托给创建Db对象的代码。
另外对我而言,与其他语言相比,您似乎不了解Singletons如何在PHP中工作。例如,如果你有10.000个并发请求,那么每个请求都在一个单独的PHP进程或线程中运行,这意味着它们都将拥有自己的“singleton”实例。
PHP中没有“连接池”,但您可以为mysql使用mysqli
个持久连接。可以通过在创建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");
}