2009-09-09 7 views
5

Ich habe eine ziemlich große Website und jede Seite ist aus mehreren enthaltenen Dateien gebaut, meine Website ist 100% in einem prozeduralen Format und ich versuche zu lernen, Klassen und eine mehr OOP-Ansatz in PHP zu verwenden.Sollte ich in PHP immer wieder mit mysql verbinden?

Derzeit hat meine Website eine Header-Datei, die in jeder Seite enthalten ist, in diesem Header ist eine mysql-Verbindung, die gemacht wird und dauern die Dauer der Seite, also wenn ich 10 verschiedene Abfragen von verschiedenen Dateien ausführen müssen Alle laufen, ohne dass eine neue Verbindung hergestellt werden muss, daher wird die Verbindung nur einmal hergestellt.

Jetzt, da ich versuche, zu einem OO-Weg zu konvertieren, beginne ich mit dem Schreiben einer MySQL-Klasse zum Verbinden und Ausführen von Abfragen, also denke ich über die Verwendung der Klassen __construct-Funktion, um eine Verbindung zu MySQL herzustellen, bin ich nur neugierig, wie das funktionieren würde, jedes Mal, wenn diese Klasse aufgerufen wird, würde sie statt nur einmal eine Verbindung zu MySQL herstellen oder versuchen.

Vielleicht denke ich nicht klar darüber nach. Soll ich diese Klasse erst einmal in der Kopfzeile initiieren und muss mir dann keine Sorgen mehr machen?

Antwort

6

Sie könnten ein einzelnes globales Objekt Ihrer MySQL-Klasse erstellen und dieses Objekt überall verwenden. Dann würde Ihr Konstruktor nur einmal aufgerufen werden.

Oder Sie könnten überall neue Objekte Ihrer MySQL-Klasse erstellen. mysql_connect keine neue Verbindungen geöffnet werden, wenn es bereits geöffnet ist:

Wenn ein zweiter Anruf() mit den gleichen Argumenten wie mysql_connect gemacht wird, wird keine neue Verbindung aufgebaut werden, aber die Verbindungskennung von der Stelle, Der bereits geöffnete Link wird zurückgegeben.

+0

Sie könnten auch eine separate singuläre Klasse für die Verbindung mit der Datenbank schreiben, so dass nur eine Verbindung geöffnet wird, sie ist konsistent und sie ist DRY. –

+1

Eh ... ich meine Singleton-Klasse. Oh, wie ich diese Wochen hasse, die nichts als montags haben ... –

+0

Ja, das ist eine andere Lösung, an die ich nicht gedacht habe. –

-2

Sie können diese Methode verwenden, wenn Sie die Funktion mysql_pconnect() verwenden, die suchen wird, wenn es bereits eine mysql-Verbindung gibt, und falls sie gefunden wird, würde sie keine andere erstellen.

In Alternative, wenn man bedenkt, noch Fälle, in PHP zu verwenden, können Sie PHP-Datenbankobjekt direkt, wie nennen:

class DB {} 

DB::connect($host, $user, $pass); 

Wenn Sie diese Methode verwenden, müssen Sie nicht über mehrere Verbindungen kümmern . Natürlich können Sie, wenn Sie mehrere Verbindungen zu mehr als einer Datenbank gleichzeitig benötigen, Objektinstanzen verwenden oder Ihre Klasse so einrichten, dass sie mehrere Parameter gleichzeitig aufnehmen und speichern kann (nicht sehr empfohlen).

+0

Fehlinformationen über die Verwendung von mysql_pconnect() nicht falsch. –

+0

mysql_pconnect: Zuerst versucht die Funktion beim Verbindungsaufbau, zuerst einen (persistenten) Link zu finden, der bereits mit demselben Host, Benutzernamen und Passwort geöffnet ist. Wenn eine gefunden wird, wird eine ID zurückgegeben, anstatt eine neue Verbindung zu öffnen. Quelle: php.net was ist wieder falsch? – yoda

1

Ja, Sie sollten nicht mehrmals verbinden. Der Aufwand, die Verbindung ständig zu öffnen und zu schließen, ist größer als die Kosten, sie während der relativ kurzen Zeit, in der Ihre Skripte laufen, offen zu halten. Daher sollten Sie am Anfang eine Instanz der Klasse erstellen und diese in einer globalen Variablen speichern.

Es ist sicherlich keine schlechte Idee, eigene Klassen als Übung zu schreiben, aber vielleicht sollten Sie sich eine der vorhandenen Lösungen für das Datenbankverbindungsmanagement (Zend_Db etc.) ansehen.

0

Sie können die Datenbankverknüpfungsreferenz immer in einer STATIC-Klassenvariablen speichern und bei Bedarf aufrufen. PHP versucht jedoch selbst, eine vorhandene Verknüpfung zu verwenden, wenn sie im Speicher vorhanden ist.

Ich habe einen Beispiel-Datenbank-Handler-Code für Sie, natürlich seine PHP 5 und verwendet PDO.

<?php 
// Class providing generic data access functionality 
class DatabaseHandler 
{ 
    // Hold an instance of the PDO class 
    private static $_mHandler; 

    // Private constructor to prevent direct creation of object 
    private function __construct() 
    { 
    } 

    // Return an initialized database handler 
    private static function GetHandler() 
    { 
    // Create a database connection only if one doesn’t already exist 
    if (!isset(self::$_mHandler)) 
    { 
     // Execute code catching potential exceptions 
     try 
     { 
     // Create a new PDO class instance 
     self::$_mHandler = 
      new PDO(PDO_DSN, DB_USERNAME, DB_PASSWORD); 

     // Configure PDO to throw exceptions 
     self::$_mHandler->setAttribute(PDO::ATTR_ERRMODE, 
             PDO::ERRMODE_EXCEPTION); 
     self::$_mHandler->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); 
     } 
     catch (PDOException $e) 
     { 
     // Close the database handler and trigger an error 
     self::Close(); 
     trigger_error($e->getMessage(), E_USER_ERROR); 
     } 
    } 

    // Return the database handler 
    return self::$_mHandler; 
    } 
    // Clear the PDO class instance 
    public static function Close() 
    { 
    self::$_mHandler = null; 
    } 
    // Wrapper method for PDO::prepare 
    private static function Prepare($queryString) 
    { 
    // Execute code catching potential exceptions 
    try 
    { 
     // Get the database handler and prepare the query 
     $database_handler = self::GetHandler(); 
     $statement_handler = $database_handler->prepare($queryString); 

     // Return the prepared statement 
     return $statement_handler; 
    } 
    catch (PDOException $e) 
    { 
     // Close the database handler and trigger an error 
     self::Close(); 
     trigger_error($e->getMessage(), E_USER_ERROR); 
    } 
    } 

    // Wrapper method for PDOStatement::execute() 
    public static function Execute($sqlQuery, $params = null) 
    { 
    // Try to execute an SQL query or a stored procedure 
    try 
    { 
     $statement_handler = self::Prepare($sqlQuery); 

     // Execute query 
     $statement_handler->execute($params); 
    } 
    // Trigger an error if an exception was thrown when executing the SQL query 
    catch(PDOException $e) 
    { 
     // Close the database handler and trigger an error 
     self::Close(); 
     trigger_error($e->getMessage(), E_USER_ERROR); 
    } 
    } 

    // Wrapper method for PDOStatement::fetchAll() 
    public static function GetAll($sqlQuery, $params = null, 
           $fetchStyle = PDO::FETCH_ASSOC) 
    { 
    // Initialize the return value to null 
    $result = null; 

    // Try to execute an SQL query or a stored procedure 
    try 
    { 
     $statement_handler = self::Prepare($sqlQuery); 

     // Execute the query 
     $statement_handler->execute($params); 

     // Fetch result 
     $result = $statement_handler->fetchAll($fetchStyle); 
    } 
    // Trigger an error if an exception was thrown when executing the SQL query 
    catch(PDOException $e) 
    { 
     // Close the database handler and trigger an error 
     self::Close(); 
     trigger_error($e->getMessage(), E_USER_ERROR); 
    } 

    // Return the query results 
    return $result; 
    } 

    // Wrapper method for PDOStatement::fetch() 
    public static function GetRow($sqlQuery, $params = null, 
           $fetchStyle = PDO::FETCH_ASSOC) 
    { 
    // Initialize the return value to null 
    $result = null; 

    // Try to execute an SQL query or a stored procedure 
    try 
    { 

     $statement_handler = self::Prepare($sqlQuery); 

     // Execute the query 
     $statement_handler->execute($params); 

     // Fetch result 
     $result = $statement_handler->fetch($fetchStyle); 
    } 
    // Trigger an error if an exception was thrown when executing the SQL query 
    catch(PDOException $e) 
    { 
     // Close the database handler and trigger an error 
     self::Close(); 
     trigger_error($e->getMessage(), E_USER_ERROR); 
    } 

    // Return the query results 
    return $result; 
    } 

    // Return the first column value from a row 
    public static function GetOne($sqlQuery, $params = null) 
    { 
    // Initialize the return value to null  
    $result = null; 

    // Try to execute an SQL query or a stored procedure 
    try 
    { 
     $statement_handler = self::Prepare($sqlQuery); 

     // Execute the query 
     $statement_handler->execute($params); 

     // Fetch result 
     $result = $statement_handler->fetch(PDO::FETCH_NUM); 

     /* Save the first value of the result set (first column of the first row) 
     to $result */ 
     $result = $result[0]; 
    } 
    // Trigger an error if an exception was thrown when executing the SQL query 
    catch(PDOException $e) 
    { 
     // Close the database handler and trigger an error 
     self::Close(); 
     trigger_error($e->getMessage(), E_USER_ERROR); 
    } 

    // Return the query results 
    return $result; 
    } 
} 
?> 
0

Sie sollten eine Verbindung Objekt übergeben (wahrscheinlich PDO) um, und die verschiedenen Orte sollen, dass abholen können, entweder als Parameter oder als Eigenschaft von einem zentralen Objekt, das die andere einen Verweis zu oder etwas.

Mehrere Verbindungen können nützlich sein, es scheint verrückt, dass mysql_connect eine bestehende Verbindung aufnimmt, wenn Sie eine neue haben wollten - aber es ist sowieso verrückt. Verwenden Sie einfach PDO.

2

Der beste Weg, ich denke, ist die Verwendung einer speziellen Klasse, um MySQL-Verbindungen zu behandeln und es als Singleton zu verwenden. Machen Sie den Konstruktor privat und lassen Sie ihn eine Instanz einer bestehenden oder einer neuen Verbindung zurückgeben.

Hier ist mein Beispiel:

class db 
{ 

    public $host; 
    public $user; 
    public $pass; 
    public $database; 

    private static $instance = false; 

    private function __construct() 
    { 

    } 

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

     public function db_connect() 
     { 
     } 

     public function db_disconnect() 
     { 
     } 
} 

Auf diese Weise, wenn Sie anrufen: db :: getInstance() -> db_connect(), Sie sind sicher, dass es nur geht zu sein, eine Instanz dieser Verbindung überall.

+0

Ich schaue gerade jetzt auf dieses als Referenz zurück. Ich bin ein wenig verwirrt, Sie haben es als db :: getInstance() -> db_connect() muss ich db :: getInstance() -> METHODNAME-HIER für jede Methode, die ich in der DB-Klasse aufrufen? Wenn ich eine Methode namens execute() habe, die ich auch eine SQL-Abfrage übergebe, müsste ich das so machen, db :: getInstance() -> execute ($ sql)? Danke für die Hilfe – JasonDavis