2009-09-09 11 views
5

Ho un sito piuttosto grande e ogni pagina è composta da diversi file inclusi, il mio sito è al 100% in un formato procedurale e sto cercando di imparare a utilizzare le classi e un approccio OOP in PHP.Devo continuare a riconnettersi a mysql in PHP?

Attualmente il mio sito ha un file di intestazione che è incluso in ogni pagina, in questa intestazione è una connessione mysql creata e dura la durata della pagina, quindi se ho bisogno di eseguire 10 query diverse da file diversi, esse tutti funzionano senza bisogno di creare una nuova connessione, quindi la connessione viene eseguita una sola volta.

Ora che sto cercando di convertire in un modo OO, sto iniziando a scrivere una classe mysql per connettere ed eseguire query, quindi sto pensando di usare la funzione __construct per creare una connessione a mysql, sono solo curioso di sapere come funziona, ogni volta che la classe viene chiamata, farebbe o tenterà di stabilire una connessione con mysql invece che una sola volta.

Forse non sto pensando chiaramente. Devo solo iniziare questa lezione nell'intestazione 1 volta e quindi non dovrò più preoccuparmi?

risposta

6

È possibile creare un singolo oggetto globale della classe MySQL e utilizzare tale oggetto ovunque. Quindi il tuo costruttore verrà chiamato una sola volta.

Oppure puoi creare nuovi oggetti della tua classe MySQL ovunque. mysql_connect non apre nuove connessioni se c'è già un'aperta:

Se una seconda chiamata viene effettuata a mysql_connect() con gli stessi argomenti, verrà stabilito alcun nuovo collegamento, ma, invece, l'identificativo link del il collegamento già aperto verrà restituito.

+0

È anche possibile scrivere una classe singolare separata per la connessione al database, in questo modo viene aperta una sola connessione, è coerente ed è ASCIUTTA. –

+1

Eh ... Intendo classe singleton. Oh, come odio queste settimane che non hanno altro che i lunedì ... –

+0

Sì, questa è un'altra soluzione a cui non ho pensato. –

-2

È possibile utilizzare tale metodo se si utilizza la funzione mysql_pconnect(), che cercherà se esiste già una connessione mysql e nel caso in cui la trovi, non ne creerà un'altra.

In alternativa, se si considera né di utilizzare le istanze in PHP, è possibile chiamare oggetto di database php direttamente, come:

class DB {} 

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

Se si utilizza questo metodo, non c'è bisogno di preoccuparsi di connessioni multiple . Ovviamente, se hai bisogno di utilizzare più connessioni a più di un database alla volta, puoi fare uso di istanze di oggetti o creare la tua classe in modo che possa prendere diversi parametri e archiviarli tutti in una volta (non molto ricomposta questa)

+0

Non disinformare l'uso di mysql_pconnect(). –

+0

mysql_pconnect: in primo luogo, al momento della connessione, la funzione cercherebbe innanzitutto di trovare un collegamento (persistente) già aperto con lo stesso host, nome utente e password. Se ne viene trovato uno, verrà restituito un identificatore per esso anziché aprire una nuova connessione. fonte: php.net cosa c'è di nuovo sbagliato? – yoda

1

Sì, non è necessario connettersi più volte. Il sovraccarico di aprire e chiudere la connessione tutto il tempo è più grande del costo di tenerlo aperto durante il relativo breve periodo di esecuzione degli script. Quindi dovresti creare un'istanza della classe all'inizio e mantenerla in una variabile globale.

Non è certo una cattiva idea scrivere le tue lezioni come esercizio, ma forse dovresti esaminare una delle soluzioni esistenti per la gestione della connessione al database (Zend_Db ecc.).

0

È sempre possibile memorizzare il riferimento del collegamento del database in una variabile di classe STATIC e chiamarlo quando necessario. Tuttavia, PHP da solo tenta di utilizzare un collegamento esistente se esiste nella memoria.

Ho un codice di gestione database di esempio per te, naturalmente il suo PHP 5 e utilizza 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

si dovrebbe passare un oggetto di connessione (probabilmente DOP) in giro, e le varie località dovrebbe essere in grado di raccogliere che fino, sia come parametro, o come una proprietà di un oggetto centrale che gli altri hanno un riferimento a, o qualcosa.

Avere più connessioni può essere utile, sembra folle che mysql_connect prelevi una connessione esistente quando potresti averne voluto una nuova - ma è comunque folle. Basta usare PDO.

2

Il modo migliore è utilizzare una classe speciale per gestire le connessioni mysql e utilizzarla come un singleton. Rendi privato il costruttore e fallo restituire un'istanza di una connessione esistente o nuova.

Ecco il mio esempio:

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() 
     { 
     } 
} 

In questo modo, quando si chiama: db :: getInstance() -> db_connect(), si è certi non solo andando a essere un'istanza di tale connessione in tutto il mondo.

+0

Sto solo ora guardando a questo per riferimento. Sono un po 'confuso, lo avete come db :: getInstance() -> db_connect() ho bisogno di usare db :: getInstance() -> METHODNAME-HERE per ogni metodo che chiamo nella classe DB? Se ho un metodo chiamato execute() che passo anche a una query SQL dovrei farlo in questo modo, db :: getInstance() -> execute ($ sql)? Grazie per l'aiuto – JasonDavis

Problemi correlati