[英]PHP singleton database connection pattern
我一直在使用 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 訪問者並且我每次都調用我的單例對象,我應該期望有性能問題嗎? 我的意思是,我不應該有一種連接池而不是單例嗎?
在 PHP 中使用singletons
被認為是不好的做法。 根據我的經驗,它們最有問題的問題是單元測試。 在測試單例時,很難確保兩個測試是獨立的。
我會將約束“只應存在一個實例”的責任委托給創建 Db 對象的代碼。
同樣對我來說,與其他語言相比,單例在 PHP 中的工作方式似乎存在誤解:例如,如果您有 10.000 個並發請求,那么每個請求都在單獨的 PHP 進程或線程中運行,這意味着它們都有自己的“singleton”的實例,對於一個以上的請求,沒有共享此對象(在常見的 Web 后端場景中運行 PHP 時)
PHP 中沒有“連接池”,但您可以對 mysql 使用mysqli
持久連接。 可以通過在創建 mysqli 時在主機名前面傳遞p:
來實現。 這在這里可能會有所幫助,但要小心處理(意思是先閱讀文檔)
然而,只是為了理論上,PHP 中的單例必須知道有人可以使用clone
。 這意味着在您的情況下可以這樣做:
$db = DB::getInstance();
$db2 = clone $db;
為了避免這種情況,您可以像這樣實現__clone()
方法:
public function __clone() {
throw new Exception("Can't clone a singleton");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.