¿Quieres registrarte?

Crear una clase para conectar a base de datos con PHP (II)

Por: marcosdev
6 de Noviembre del 2008

En un post anterior vimos como crear una clase muy sencilla la cual podía ser instanciada varias veces (patrón de diseño Singleton) sin que nos produjese la creación de varios objectos ni la creación de más conexiones concurrentes.

En en esta segunda parte vamos a ver cómo crear una clase, siguiendo también el patrón Singleton, que sea capaz de leer un fichero de configuración. En este fichero de configuración aparecerán los parámetros de conexión a nuestra base de datos, además de otros valores que puedan ser interesantes para nuestra aplicación. Con ello, haremos que nuestras clases sean reutilizables sin la necesidad de editarlas para adaptarlas al proyecto de turno.

Lo primero de todo veamos la estructura del fichero de configuración:

config.php

Código :

//Datos de configuración de la conexión a la base de datos

//Servidor
$host='localhost';

//Usuario
$user='user';

//Password
$password='test';

//Base de datos a utilizar
$db='testDB';



La estructura de este fichero es muy sencilla y se limita a un conjunto de variables que contiene la información necesaria para conectarse a la base de datos.

Ahora veamos la estructura de la clase Conf

Conf.class.php

Código :

Class Conf{
   private $_domain;
   private $_userdb;
   private $_passdb;
   private $_hostdb;
   private $_db;

   static $_instance;

   private function __construct(){
      require 'config.php';
      $this->_domain=$domain;
      $this->_userdb=$user;
      $this->_passdb=$password;
      $this->_hostdb=$host;
      $this->_db=$db;
   }

   private function __clone(){ }

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

   public function getUserDB(){
      $var=$this->_userdb;
      return $var;
   }

   public function getHostDB(){
      $var=$this->_hostdb;
      return $var;
   }

   public function getPassDB(){
      $var=$this->_passdb;
      return $var;
   }

   public function getDB(){
      $var=$this->_db;
      return $var;
   }

}


Como podemos observar en el código, lo único que hace esta clase es la inclusión del fichero de configuración y la importación de los valores de las variables a variables privadas de la clase. Mediante métodos podremos obtener los valores que necesitemos de la configuración sin peligro de sobreescribir ninguno de los valores, algo que si requiriésemos el fichero config.php en cualquier lugar, sería muy probable que nos pasase. Ahora debemos realizar algunas modificaciones sencillas dentro del fichero de nuestra clase de base de datos, Db.class.php:

Código :

/* Clase encargada de gestionar las conexiones a la base de datos */
Class Db{

   private $servidor;
   private $usuario;
   private $password;
   private $base_datos;
   private $link;
   private $stmt;
   private $array;

   static $_instance;

   /*La función construct es privada para evitar que el objeto pueda ser creado mediante new*/
   private function __construct(){
      $this->setConexion();
      $this->conectar();
   }

   /*Método para establecer los parámetros de la conexión*/
   private function setConexion(){
      $conf = Conf::getInstance();
      $this->servidor=$conf->getHostDB();
      $this->base_datos=$conf->getDB();
      $this->usuario=$conf->getUserDB();
      $this->password=$conf->getPassDB();
   }

   /*Evitamos el clonaje del objeto. Patrón Singleton*/
   private function __clone(){ }

   /*Función encargada de crear, si es necesario, el objeto. Esta es la función que debemos llamar desde fuera de la clase para instanciar el objeto, y así, poder utilizar sus métodos*/
   public static function getInstance(){
      if (!(self::$_instance instanceof self)){
         self::$_instance=new self();
      }
         return self::$_instance;
   }

   /*Realiza la conexión a la base de datos.*/
   private function conectar(){
      $this->link=mysql_connect($this->servidor, $this->usuario, $this->password);
      mysql_select_db($this->base_datos,$this->link);
      @mysql_query("SET NAMES 'utf8'");
   }

   /*Método para ejecutar una sentencia sql*/
   public function ejecutar($sql){
      $this->stmt=mysql_query($sql,$this->link);
      return $this->stmt;
   }

   /*Método para obtener una fila de resultados de la sentencia sql*/
   public function obtener_fila($stmt,$fila){
      if ($fila==0){
         $this->array=mysql_fetch_array($stmt);
      }else{
         mysql_data_seek($stmt,$fila);
         $this->array=mysql_fetch_array($stmt);
      }
      return $this->array;
   }

   //Devuelve el último id del insert introducido
   public function lastID(){
      return mysql_insert_id($this->link);
   }

}



Podemos ver que en la clase hay un nuevo método privado llamado setConexion() el cual se encarga de instanciar el objeto de la clase Conf y establecer el valor de las variables privadas que tenemos en la clase Db. Luego el proceso es el mismo que en la primera parte del tutorial.

Veamos cómo debería quedar el código de ejemplo para que nos funcione con la nueva clase:

Código :

/*Incluimos el fichero de la clase Db*/
require 'Db.class.php';
/*Incluimos el fichero de la clase Conf*/
require 'Conf.class.php';

/*Creamos la instancia del objeto. Ya estamos conectados*/
$bd=Db::getInstance();

/*Creamos una query sencilla*/
$sql='SELECT NOMBRE FROM CLIENTES';

/*Ejecutamos la query*/
$stmt=$bd->ejecutar($sql);

/*Realizamos un bucle para ir obteniendo los resultados*/
while ($x=$bd->obtener_fila($stmt,0)){
   echo $x['NOMBRE'].'<br />';
}


Como podemos observar, únicamente hemos añadido un require para la nueva clase creada. Nada más. En la siguiente parte del tutorial veremos cómo podemos hacer que esta clase se conecte a diferentes tipos de base de datos.

Un saludo

Temas relacionados:
Crear una clase para conectar a la base de datos

Enviar a twitter Enviar a facebook


También te interesa


Etiquetas php bases_de_datos mysql poo singleton

Comentarios | Enviar un comentario
Muy bien, para que luego digan que PHP es un lenguaje de programación malo, desordenado y poco mantenible.

Muchas gracias!!
Por: Muy bueno-blog
hola que tal vi una clase como la que quieres hacer, esta es: http://foro.elhacker.net/php/me_gustaria_compartir_mi_clase_dball_manejador_de_bases_de_datos-t175795.0.html
a ver si les sirve
Por: anonimo-blog
Sí, es algo muy parecido, pero no exacto.

Gracias
Por: marcosdev
Está bueno el ejemplo (y) good tip
Por: Zguillez
Sigo insistiendo marcosdev deberias irlo reglamentando con el PDO para que de una vez tengas una capa de conexion para cualquiera driver.

Para la clase DB extenderla de PDO y en tu metodo __construct cambiarlo a algo como esto function __construct($dsn=NULL,$username=NULL, $password=NULL, $driver_options=NULL) {
parent::__construct($dsn,$username,$password, $driver_options);
$this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('PDO_Data_Statement', array($this)));
}
y con esto utilizarias todas las funciones que trae el PDO y personalizarias algunas que tengan que ver con la capa de Modelo de tu aplicacion, con esto logras menos código e implementar una clase que de hecho ya resuelve problemas de rendimiento en los fetch para evitarte foreach innecesarios y añadiendo un manejo de errores con la robustez que promete el PDO. http://www.php.net/manual/es/book.pdo.php
Por: vanvanero
vanvanero: Has un tip usando PDO. Algunos hosting no traen habilitado PDO (no se cual será el motivo).
Este es un buen ejemplo de como empezar a usar patrones en PHP.
Felicidades marcosdev!
Por: GustavoV
Buen ejemplo tambien de lo que son las classes...

Pero creo que seria mas simple cargar la configuracion de esta manera:

Archivo Conf.php:

Código :


<?php



define(DB_HOST, 'localhost');

define(DB_NAME, 'test');

define(DB_USER, 'root');

define(DB_PASS, '');



?>




para cargar la config....

Código :


<?php



class DB {



   private $DBHOST;

   private $DBNAME;

   private $DBUSER;

   private $DBPASS;



   private function getConf($Value) {

      require('./Conf.php');

      $this->DBHOST = DB_HOST;

      $this->DBNAME = DB_NAME;

      $this->DBUSER = DB_USER;

      $this->DBPASS = DB_PASS;

      if ($Value == 'Servidor') {

         return $this->DBHOST;

      }

      if ($Value == 'Base de Datos') {

         return $this->DBNAME;

      }

      if ($Value == 'Usuario') {

         return $this->DBUSER;

      }

      if ($Value == 'Clave') {

         return $this->DBPASS;

      }

}



?>




Si despuse queremos el valor en la misma clse creo q seria solo poner, en case que quisieramos el Host de MySQL:

DB::getConf('Servidor');

Y saldra:

localhost
Por: PHPNEW-blog
Hay alguna manera de indicarle a mysql que trabaje con UTF-8 utilizando PDO?

Con las funciones conocidas de mysql, bastaba con escribir mysql_query('SET NAME UTF-8') y podía ver todos los datos de la bd correctamente.

Leí que con PDO podíamos hacerlo así: PDO::MYSQL_ATTR_INIT_COMMAND('SET NAME UTF-8'); y se lee la data con caracteres extraños.
Por: PDO Y UTF-8-blog
Buenas,

Me sabe mal no poderte responder a esa pregunta ya que no utilizo la extensión PDO. Actualmente utilizo la extensión mysqli más la implementación de clases VO y DAO, que construyo.

Un saludo
Por: marcosdev
Para utilizar UTF8 en PDO debes usar:
$db->exec('SET CHARACTER SET utf8');

Saludos
Por: dannet-blog
Deja un comentario
IMPORTANTE

Recuerda ser respetuoso, no insultes a otras personas, ni uses palabrotas, hay una persona al otro lado de la pantalla.

Habla bien, NO ESCRIBAS EN MAYUSCULA TODO, no escribas como en un SMS, evita cosas como "ke", "x q" y demás abreviaciones.

Aquí funcionan las etiquetas de los foros, puedes usar [b] para negrita, [img] para las imágenes, [url] para los enlaces, etc.

Si tienes preguntas técnicas, envíalas mejor al foro.