簡體   English   中英

PHP單例數據庫連接模式

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM