2013-11-26 21 views
-1

這是足夠讓php在單身人士?MySQLi Singleton

public static function getInstance() { 
    if (!isset(self::$intance)) { 
    self::$instance = new mysqli(DB_HOST, DB_USER, DB_PWD, DB_NAME); 
    } 
    return self::$instance; 
} 

我發現它是最簡單的方式,比我在這裏看到的任何東西都容易。那有什麼問題嗎?

+0

您也可以嘗試永久連接。 – hjpotter92

+2

如果(!isset(self :: $ intance)){'to'if(!isset(self :: $ instance)){''除非是拼寫錯誤。 –

+1

對於單例使用情況已經足夠了,如果您需要強制實現獨特性,您還可以使構造函數保持私有狀態,並在'__clone()'中引發異常,但是,就是這樣。如果你不需要執行它,你甚至可以使用一個帶有'static'變量的正常函數,避免需要類變量/可能直接訪問它。 – Wrikken

回答

-1

鞏固評論中的變化,用我自己的。不是依賴常量,而是將變量傳遞給getInstance /構造函數,以便您可以以任何您想要的方式存儲憑據,並將它們饋送到類中,而不必依賴於以某種方式存儲的數據。增加了一點靈活性。

你也可以將它與代碼交換,從配置文件讀取它們,或者從服務定位器類型模式中獲取數據。

Class MysqlConnection { 
    private static $instance = null; 
    private function __construct() { 
    self::$instance = new mysqli(DB_HOST,DB_USER,DB_PASS,DB_DATABASE); 
    } 

    public static function getInstance() { 
    if (!isset(self::$instance)) { 
     $credentials = self::getCredentials(); 
     self::$instance = new MysqlConnection(); 
    } 
     return self::$instance; 
    } 
    } 

    function __clone() { 
    //Throw exception/custom exception type here. 
    } 
} 

編輯點評:這個想法是因爲是階級這裏不是勾勒一個完全100%使用,但是代表我的立場和態度這一點。憑證位不是100%必需的,它只是我覺得讓它更靈活一些,而不是將其編碼爲僅使用CONSTANTS等。這可能會從初始點分散注意力,這是單身人士看起來的樣子。我對這種混亂表示歉意。

+1

每次調用'getInstance'時,你都不會**想要傳遞主機,用戶,密碼和db名稱。此外,你的類缺少靜態'$ instance'屬性。另外,構造函數不返回任何東西。 – Phil

+0

糾正所有計數。我想我匆匆穿過這個例子。編輯傳入來修復該問題。 –

0

你不能讓原來的mysqli類成爲一個單身人士 - 這實際上是一件好事,因爲單身人士是邪惡的(如果需要,我會詳細討論這一點)。

你所做的是在技術上稱爲靜態工廠方法,它將只返回有史以來第一個創建的數據庫對象實例。這實際上比使用單例更好,因爲您也可能刪除該實例以進行測試以創建另一個實例,而另一個實例...

但是根據我的經驗,您通常很樂意有一種方法來使用您的代碼中不只有一個數據庫連接。只需考慮使用兩個用戶帳戶,一個用於管理員用戶,另一個用於常規用途。僅此一項就有資格作爲兩個數據庫連接,如果您的代碼只能處理「唯一的一個實例」而沒有選擇登錄憑證,這將是一件非常糟糕的事情。我建議反對它。

0

這是單例類:

class DataBase 
{ 
    private static $mysqli; 

    final private function __construct() {} 

    public static function getInstance() 
    { 
    if (!is_object(self::$mysqli)) self::$mysqli = new mysqli($H,$U,$P,$B); 
    return self::$mysqli; 
    } 

    private function __destruct() 
    { 
    if (self::$mysqli) self::$mysqli->close(); 
    } 

    private function __clone() {} 
} 

這一點很重要:

  • 變量(存儲數據庫連接)是靜態
  • 構造函數是私有的(不能叫)(終是不能被覆蓋)
  • 函數返回對象也是靜態的(通常函數getInstance如此處)
  • 克隆單類是不允許這樣__clone()函數必須是空的
  • 析構函數__destruct通過垃圾收集器調用和應該完成狀態

所以這種數據庫連接從其他類稱爲:

$db=DataBase::getInstance(); 

不是

$db=new DataBase();