2009-10-16 7 views
14

So kürzlich habe ich wirklich begonnen, PHP aktiv zu verwenden, und ich brauche einige Einblicke in verschiedene Möglichkeiten, Datenbankverbindungen zu verwenden.Wie verwalten Sie Datenbankverbindungen in PHP?

Zuerst habe ich nur die einfache mysql_connect():

<?php 
    $connection = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die(mysql_error()); 
    mysql_select_db(DB_DB, $connection); 
?> 

Nach einer Weile habe ich eine Datenbank-Klasse erstellt, die ich begann, in jeder Datei aufzunehmen und zu initialisieren - etwa so:

<?php 
class MySQL_DB { 

var $connection; 

function MySQL_DB(){ 
    $this->connection = mysql_connect(DB_HOST, DB_USER, DB_PASS) or die(mysql_error()); 
    mysql_select_db(DB_DB, $this->connection); 
} 

function query($q){ 
    $res = mysql_query($q, $this->connection) or die(mysql_error()); 
    return $res; 
} 
} 

$database = New MySQL_DB; 
?> 

Und das ist, was ich zu der Zeit verwende - und es funktioniert gut - aber es gibt immer Möglichkeiten, um zu verbessern.

Also meine Frage an Sie ist, wie Sie Ihre Datenbankverbindungen verwalten?

  • Verwenden Sie Klassen?
  • Was enthält Ihre Klasse (nur die Verbindung oder sogar Funktionen?)
  • Welche Praktiken empfehlen Sie?

Antwort

3

Die Verwendung von Klassen ist der Weg, um die benutzerdefinierte Wiederverwendbarkeit zu erhöhen.

Geben Sie alle generischen Implementierungen in die Klasse ein. Du bist auf dem richtigen Weg.

This website has the following clean approach .

class connection { 
    // Possible Modules are as follows: 
    // DBX_MYSQL, DBX_ODBC, DBX_PGSQL, DBX_MSSQL, DBX_FBSQL, DBX_SYBASECT, DBX_OCI8, DBX_SQLITE 
    private $module = DBX_MYSQL; 

    private $host = "localhost"; 
    private $database = "test"; 
    private $username = "testuser"; 
    private $password = "testpass"; 

    private $link; 
    private $result; 
    public $sql; 

    function __construct($database=""){ 
      if (!empty($database)){ $this->database = $database; } 
      $this->link = dbx_connect($this->module,$this->host,$this->database,$this->username,$this->password); 
      return $this->link; // returns false if connection could not be made. 
    } 

    function query($sql){ 
      if (!empty($sql)){ 
        $this->sql = $sql; 
        $this->result = dbx_query($this->link,$sql,DBX_RESULT_UNBUFFERED); 
        return $this->result; 
      }else{ 
        return false; 
      } 
    } 

    function fetch($result=""){ 
      if (empty($result)){ $result = $this->result; } 
      return dbx_fetch_row($result); 
    } 

    function __destruct(){ 
      dbx_close($this->link); 
    } 
} 
+0

Ich mochte wirklich die Abruffunktion auf diesem - sowie die Speicherung der Ergebnisse als Instanzvariablen. Danke für diese Eingabe +1 –

+0

-1, für zukünftige Benutzer, speichern Sie niemals Ihre Konfigurationsinformationen in der gleichen Datenbankklasse. Das ist sicher und tötet auch die Wiederverwendbarkeit. Erstellen Sie eine Konfigurationsklasse/Seite und verwenden Sie Konstanten oder etwas, um sie an die Verbindungsklasse zu übergeben. –

9

Ich empfehle, PDO zu verwenden. Erfinde das Weel nicht neu. Es ist eine nette OO-Schnittstelle zu many database engines. Zusätzlich erstelle ich eine kleine Funktion, die nur PDO-Objekt initialisiert. So können alle Verbindungseinstellungen an einer Stelle geändert werden.

4

Ihr aktueller Ansatz ist ziemlich Standard, und funktioniert gut. Ich habe es lange benutzt. Es ist wahr, dass Module wie PDO jetzt eine Basisfunktionalität wie diese bereitstellen, was auch sehr nett ist und Sie von Problemen mit selbstgebrautem Code befreien kann.

Allerdings habe ich das Verbindungsmanagement noch einen Schritt weiter geführt. Wenn Sie in eine komplexe Anwendung geraten, geraten Sie möglicherweise in eine Situation, in der Sie mehrere Datenbanken oder eine starke Datenbank verwenden. Das Einfügen einer einzelnen Datenbankverbindungsdatei und einer globalen $database-Variablen wird für mehrere Datenbanken unhandlich, und für Anwendungsanforderungen, die möglicherweise nicht benötigen, ist eine Datenbankverbindung nicht erforderlich. Denken Sie daran, dass die Verbindung zur Datenbank teuer ist.

Was ich getan habe, ist eine Singleton DatabaseManager-Klasse zu erstellen, die das Datenbankobjekt für mich behandelt, und stellt sicher, dass mehrere Verbindungen zu einem bestimmten DB nicht instanziiert werden. Anstatt ein neues Datenbankobjekt am Anfang Ihrer App zu initialisieren, rufen Sie den DatabaseManager einfach jedes Mal auf, wenn Sie das Objekt benötigen.

Hier ist eine Beispielklasse, die ich für ein CodeIgniter-Projekt ausgepeitscht hatte. Sie können in der getDatabase() Funktion sehen, es lädt einfach CodeIgniter das Standard-Datenbank-Objekt, das Sie für Ihre eigene Klasse ersetzen würden (und führen Sie die Verbindungsroutine für es), wenn Sie CI nicht verwenden.Dies ist eine ziemlich einfache Verwaltungsklasse und könnte so erweitert werden, dass mehrere Verbindungen zu verschiedenen Datenbanken relativ einfach verwaltet werden können.

<?php 

/** 
* Implements the Singleton pattern to prevent multiple instantiations and connections 
* to the application database. 
* 
*/ 
class Database_manager 
{ 
    private static $instance; 
    public $db; 

    /** 
    * Constructor function is declared private to prevent instantiation. 
    * 
    */ 
    protected function __construct() 
    { 
     parent::__construct(); 
    } 

    /** 
    * Returns an instance of a Database_manager. 
    * 
    * @return object Database_manager object 
    */ 
    public static function getInstance() 
    { 
     if (self::$instance == null) { 
      $className = __CLASS__; 
      self::$instance = new $className(); 
     } 
     return self::$instance; 
    } 

    public static function getDatabase() 
    { 
     $instance = self::getInstance(); 
     if ($instance->db == null) { 
      //utilize CodeIgniter's database loader 
      $instance->db = $instance->load->database('',true); 
      if (! is_object($instance->db)) throw new Exception("Could not load database."); 
     } 
     return $instance->db; 
    } 
} 

Vielleicht die häufigste Vorteil, den ich aus der Verwendung dieser Art von Verbindungsmanagement erhalten ist, wenn ich eine Anwendung für die Pflege der Datenbank herunterzunehmen haben. Indem ich eine Datenbankverbindung nicht instanziiert, bis ich sie benötige, kann ich einfach eine "Wartung läuft" -Nachricht auf einer Site erstellen (Kurzschließen des normalen MVC-Versands) und sich nicht um Anfragen an die Anwendung kümmern, die eine DB-Verbindung öffnet, während die Wartung läuft Fortschritt.

0

In Ihrem Beispiel für den Datenbankmanager haben Sie kein übergeordnetes Element für Ihre Klasse definiert. Daher ruft das Aufrufen von parent :: __ constructor() die Ausnahme auf. Außerdem können Sie die Eigenschaft load von code ignitor nicht verwenden.

Welche Klasse haben Sie als Erweiterung für Ihren DatabaseManager verwendet?

Da ich nicht weiß, wo Sie Ihren DatabaseManager-Code platziert haben und welche Klasse Sie als Eltern verwendet haben, habe ich die Ausnahmen umgangen, indem ich der getDatabase() -Methode einen Eingabeparameter namens $ loader übergeben habe. Normalerweise ist dieses $ loader-Objekt die Modellklasse, die Zugriff auf eine Datenbank erfordert.

public static function getDatabase($loader) 
{ 
    $instance = self::getInstance(); 
    if ($instance->db == null) { 
      //utilize CodeIgniter's database loader 
      $instance->db = $loader->load->database('default',true); 
      if (! is_object($instance->db)) throw new Exception("Could not load database."); 
    } 
    return $instance->db; 
} 

Mit freundlichen Grüßen.