2009-09-09 15 views
5

Tengo un sitio bastante grande y cada página está construida a partir de varios archivos incluidos, mi sitio es 100% en formato de procedimiento y estoy tratando de aprender a usar clases y un enfoque más OOP en PHP.¿Debo continuar volviendo a conectarme a mysql en PHP?

Actualmente mi sitio tiene un archivo de encabezado que se incluye en cada página, en este encabezado hay una conexión de MySQL y la duración de la página, por lo que si necesito ejecutar 10 consultas diferentes desde diferentes archivos, todo se ejecuta sin necesidad de hacer una nueva conexión, por lo que la conexión solo se realiza una vez.

Ahora que estoy tratando de convertir a una forma más OO, estoy empezando con la escritura de una clase mysql para conectar y ejecutar consultas, así que estoy pensando en usar la función __construct de clases para hacer una conexión a mysql, soy Sin embargo, es curioso cómo funcionaría esto, cada vez que se llama a la clase, haría o intentaría establecer una conexión con mysql en lugar de solo una vez.

Tal vez no lo estoy pensando claramente. ¿Debería iniciar esta clase en el encabezado 1 vez y luego ya no tendré que preocuparme más?

Respuesta

6

Puede crear un solo objeto global de su clase MySQL y usar ese objeto en cualquier lugar. Entonces su constructor solo se llamaría una vez.

O podría crear nuevos objetos de su clase MySQL en cualquier lugar. mysql_connect no se abre nuevas conexiones si ya hay uno abierto:

Si se realiza una segunda llamada a mysql_connect() con los mismos argumentos, no se establecerá un nuevo enlace, pero en cambio, el identificador de enlace de la el enlace ya abierto será devuelto.

+0

También podría escribir una clase singular separada para conectarse a la base de datos, de esa manera solo se abre una conexión, es consistente y está SECA. –

+1

Eh ... quiero decir clase de singleton. Oh, cómo odio estas semanas que no tienen más que lunes ... –

+0

Sí, esa es otra solución en la que no pensé. –

-2

Puede utilizar ese método si usa la función mysql_pconnect(), que buscará si ya hay una conexión mysql y, en caso de que la encuentre, no creará otra.

En alternativa, si se tiene en cuenta ni a utilizar instancias en php, puede llamar al objeto de base de datos php directamente, como:

class DB {} 

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

Si se utiliza este método, no es necesario que preocuparse de múltiples conexiones . Por supuesto que si necesita usar varias conexiones a más de una base de datos a la vez, puede hacer uso de instancias de objetos, o hacer su clase para que pueda tomar varios parámetros y almacenarlos todos a la vez (no muy recomendado)

+0

No desinformar sobre el uso de mysql_pconnect(). –

+0

mysql_pconnect: Primero, al conectarse, la función primero intentaría encontrar un enlace (persistente) que ya esté abierto con el mismo host, nombre de usuario y contraseña. Si se encuentra uno, se le devolverá un identificador en lugar de abrir una nueva conexión. fuente: php.net ¿Qué pasa de nuevo? – yoda

1

Sí, no debe conectar varias veces. La sobrecarga de abrir y cerrar la conexión todo el tiempo es mayor que el costo de mantenerla abierta durante el tiempo relativamente corto que se ejecutan los scripts. Por lo tanto, debe crear una instancia de la clase al principio y mantenerla en una variable global.

Definitivamente no es una mala idea escribir sus propias clases como un ejercicio, pero tal vez debería considerar una de las soluciones existentes para la gestión de conexión de bases de datos (Zend_Db, etc.).

0

Siempre puede almacenar la referencia de enlace de la base de datos en una variable de clase STATIC y llamarla siempre que sea necesario. Sin embargo, PHP por sí mismo intenta usar un enlace existente si existe en la memoria.

Tengo un código de controlador de base de datos de muestra para usted, por supuesto es PHP 5 y usa 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

debe pasar un objeto de conexión (probablemente DOP) alrededor, y los diversos lugares debería ser capaz de recoger hasta que, ya sea como un parámetro, o como una propiedad de un objeto central que los otros tienen una referencia a, o algo.

Tener conexiones múltiples puede ser útil, parece una locura que mysql_connect recoja una conexión existente cuando podría haber deseado una nueva, pero de todos modos es una locura. Solo usa PDO.

2

La mejor forma en que pienso es usar una clase especial para manejar conexiones mysql y usarla como singleton. Haga que el constructor sea privado y haga que devuelva una instancia de una conexión existente o de una nueva.

Aquí está mi ejemplo:

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

De esta manera, cada vez que llame: db :: getInstance() -> db_connect(), que esté seguro de que sólo hay va a ser una instancia de esa conexión en todas partes.

+0

Ahora estoy recordando esto como referencia. Estoy un poco confundido, lo tienes como db :: getInstance() -> db_connect() ¿Necesito usar db :: getInstance() -> METHODNAME-HERE para cada método que llamo en la clase DB? Si tengo un método llamado execute() que paso una consulta SQL también, ¿debería hacerlo así, db :: getInstance() -> execute ($ sql)? Gracias por la ayuda – JasonDavis

Cuestiones relacionadas