2016-03-04 38 views
4

我有一個很常見的mysqli類爲應用程序的其他部分提供數據庫連接:幾個mysqli的查詢

class IabDB extends mysqli { 

private static $instance = null; 
// db connection config vars 
private $user = "xxx-lit"; 
private $pass = "xxx"; 
private $dbName = "xxx"; 
private $dbHost = "xxx"; 


private function __construct() { 
    parent::__construct($this->dbHost, $this->user, $this->pass, $this->dbName); 
    if (mysqli_connect_error()) { 
     exit('Connect Error (' . mysqli_connect_errno() . ') ' 
       . mysqli_connect_error()); 
    } 
    mysqli_set_charset($this, "utf8"); 
} 


public static function getInstance() { 
    if (!self::$instance instanceof self) { 
     self::$instance = new self; 
    } 
    return self::$instance; 
} 

在我的模型我retrive數據這樣它工作得很好:

$db = IabDB::getInstance(); 
    $query = $db->query("SELECT status, username, email, id FROM " . $table); 
    $items = $query->fetch_all(); 

編輯 但是,當我嘗試獲得另一個查詢的另一個實例時,我收到錯誤消息:調用成員函數fetch_all()null。

相信我:我來回試了一下。兩個查詢都是有效的,如果只使用其中任何一個,則兩個查詢都會返回結果。只是爲了完整起見,這裏是第二個與周圍的模型:

class Model { 

    public static function getItems($table) {  
      $db = IabDB::getInstance(); 
      $query = $db->query("SELECT * FROM lit_veranstaltungen"); 
      $items = $query->fetch_all(); 
      $db->close(); 
      var_dump($items); 

}}

如此看來,第二連接莫名其妙地感到不安!?

獎金問題:據我所知,顯然現在大多數人都對單身模式感到好笑,似乎對此有很好的用處?

任何幫助和選項,非常感謝!

回答

2

您的代碼對我的作品,我得到什麼實例的數量:

$db = IabDB::getInstance(); 
$query = $db->query("SELECT name FROM users limit 1"); 
$items = $query->fetch_all(); 
var_export($items); 

$db = IabDB::getInstance(); 
$query = $db->query("SELECT name FROM users limit 1,1"); 
$items = $query->fetch_all(); 
var_export($items); 

回報

array (0 => array (0 => 'John',),) 
array (0 => array (0 => 'Mike',),) 

,所以我想有一個與您運行特定查詢的錯誤。因此,您需要更好的查詢錯誤報告。你的構造改變這個

private function __construct() { 
    mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); 
    parent::__construct($this->dbHost, $this->user, $this->pass, $this->dbName); 
    $this->set_charset("utf8"); 
} 

然後確保你的PHP配置這樣

error_reporting(E_ALL); 
ini_set('display_errors',1); 

,然後再次運行代碼。

它會報告錯誤或返回一個空數組。在後一種情況下,這意味着數據庫中沒有行匹配第二個查詢條件。例如,像這樣

$db = IabDB::getInstance(); 
$query = $db->query("SELECT name FROM users WHERE 1=0"); 
$items = $query->fetch_all(); 
var_export($items); 

$db = IabDB::getInstance(); 
$query = $db->query("SELECT name FOrM users"); 
$items = $query->fetch_all(); 
var_export($items); 

代碼將返回一個空數組的第一個片段和錯誤第二:

而且,讓我建議你加入這樣的函數

public function query_params($query, $params, $types = NULL) 
{ 
    $statement = $this->prepare($query); 
    $types = $types ?: str_repeat('s', count($params)); 
    $statement->bind_param($types, ...$params); 
    $statement->execute(); 
    return $statement->get_result(); 
} 

,可以讓你簡單地使用準備好的語句與PDO:

$user = $db->query_params("SELECT * FROM users WHERE name = ?", ['Mike'])->fetch_assoc(); 

關於單身人士,如果您使用的是老式程序PHP,那麼單身人士就好。如果您使用OOP,那麼更好地實施基於依賴注入的方法。

+0

感謝您的詳細anser。你是對的:實際上有一個錯誤,但它不能解決問題,因爲它只有在那裏,如果兩個查詢都是活動的。你會看看我的編輯上面?謝謝! –

+0

您應該添加mysqli錯誤報告,如我的答案中所示。這是解決您的問題的唯一方法。它無助於知道有錯誤。你需要知道**哪一個特定的錯誤**它是 –

+0

我把這個錯誤放在我上面的編輯中:調用成員函數fetch_all()null。但請記住,如果第一個查詢被禁用,它確實會返回結果... –

0

嘗試在執行查詢後使用$query->close();

對於這種情況,單身並不是一個壞主意。但更常見的情況是,你有類似於「連接管理器」的東西,它在首次使用時創建一個mysqli對象,然後在連續調用時返回該對象,並具有與多個數據庫或不同用戶的多個連接。

事情是這樣的:

class DBConnection { 
    protected static $connections = array(); 

    public static function getConnection($connection_name = 'default') { 
     if (!isset(static::$connections[$connection_name])) { 
      static::$connections[$connection_name] = // setup connection 
      // ... error handling and stuff 
     } 

     return static::$connections[$connection_name]; 
    } 
} 

順便說一句。:在你的構造,我會使用的mysqli對象的屬性ErrorHandling中:

http://php.net/manual/de/mysqli.connect-error.php

http://php.net/manual/de/mysqli.connect-errno.php

http://php.net/mysqli_set_charset

+0

$ query-> close();將無濟於事 –

1

由於mysqli(和PDO)類構造函數是公共的,因此不能從擴展mysqli(或PDO)的類創建單例。你不能重寫公共父類的構造函數,並且讓它在繼承的子類中是私有的!嘗試一下,你會得到以下錯誤:

Fatal error: Access level to DataBase::__construct() must be public (as in class mysqli)