5 Abril 2008

Clase para manejar base de datos MySQL en PHP

Por Abel

Una de las máximas prioridades en una aplicación PHP que haga uso de una base de datos, es la organización y eficiencia del código para evitar consumo innecesario de memoria, esto es bien sabido por cualquier programador. Pero ¿qué hay de la separación del código de lógica y el de la base de datos?

El patrón Modelo-Vista-Controlador nos puede ser de gran utilidad ya que separa la lógica (controladores) de scripts que acceden y relacionan las tablas de un base de datos (modelos) y de la interfaz gráfica (vistas). Pero en ocasiones no necesitamos de tantas capas de abstracción y decidimos programar todo revuelto. Aún así, utilizar una clase para los accesos a la base de datos nos es de gran ayuda para aquello de la organización del código.

La clase que a continuación propongo utiliza un patrón llamado Singleton. Este patrón obliga a instanciar unicamente una vez la clase para evitar 2 o más conexiones simultáneas. La clase contiene métodos para ejecutar sentencias SQL, cargar resultados en forma de objetos, ver el número de consultas totales etc.

<?php

class DataBase {

	private $conexion;
	private $resource;
	private $sql;
	public static $queries;
	private static $_singleton;

	public static function getInstance(){
		if (is_null (self::$_singleton)) {
			self::$_singleton = new DataBase();
		}
		return self::$_singleton;
	}

	private function __construct(){
		$this->conexion = @mysql_connect( 'localhost', 'db_user' , 'db_password' ) );
		mysql_select_db( 'database_name' , $this->conexion );
		$this->queries = 0;
		$this->resource = null;
	}

	public function execute(){
		if( ! ( $this->resource = mysql_query( $this->sql , $this->conexion ) ) ){
			return null;
		}
		$this->queries++;
		return $this->resource;
	}

	public function alter(){
		if( ! ( $this->resource = mysql_query( $this->sql , $this->conexion ) ) ){
			return false;
		}
		return true;
	}

	public function loadObjectList(){
		if ( ! ( $cur = $this->execute() ) ){
			return null;
		}
		$array = array();
		while ( $row = @mysql_fetch_object( $cur ) ){
			$array[] = $row;
		}
		return $array;
	}

	public function setQuery( $sql ){
		if( empty( $sql ) ){
			return false;
		}
		$this->sql = $sql;
		return true;
	}

	public function freeResults(){
		@mysql_free_result( $this->resource );
		return true;
	}

	public function loadObject(){
		if ( $cur = $this->execute() ){
			if ( $object = mysql_fetch_object( $cur ) ){
				@mysql_free_result( $cur );
				return $object;
			}
			else {
				return null;
			}
		}
		else {
			return false;
		}
	}

	function __destruct(){
		@mysql_free_result( $this->resource );
		@mysql_close( $this->conexion );
	}
}
?>

Si notamos, el constructor es privado. ¿Por qué? para asegurarnos de que la clase se instancie desde dentro de sí misma. Es decir, al ejecutar el método DataBase::getInstance() llamamos al constructor y creamos una única instancia de DataBase. Si volvemos a ejecutar ese método y la clase ya ha sido instanciada antes, entonces nos devolverá la instancia. Eso es el objetivo del patrón Singleton.

Veamos entonces como hacer una conexión, ejecutar una consulta y mostrar los resultados. Se asume que los parámetros de conexión como el host, el nombre de usuario y demás se especifican directamente en la clase.

// Hacemos la conexión
$db = DataBase::getInstance();

// Supongamos que tenemos una tabla de usuarios
// Hacemos la consulta:
$db->setQuery('SELECT `id`,`nombre`,`grupo` FROM `usuarios`');

// La ejecutamos y al mismo tiempo obtenemos un arreglo de objetos
// con los campos especificados en la consulta como propiedades.
$usuarios = $db->loadObjectList();

// Los imprimimos directamente en pantalla...
foreach($usuarios as $usuario){
	echo 'ID: '.$usuario->id;
	echo 'Nombre: '.$usuario->nombre;
	echo 'Grupo: '.$usuario->grupo;
	echo '<br />';
}

Y ahí tienen un pequeñísimo ejemplo de uso. Algunos métodos como el DataBase::loadObject o DataBase::loadObjectList fueron tomados de la API de Joomla. En fin, espero que les sea de utilidad.


Technorati tags: , , , ,


Entradas posiblemente relacionadas:


Este artículo fue escrito el 5 de Abril de 2008 y se encuentra en la(s) categoría(s) de PHP, Programacion. Puedes seguir las respuestas a esta entrada a traves del Feed RSS. También puedes dejar un comentario, o hacer un trackback desde tu propio blog.

Actualmente hay 7 comentarios para “Clase para manejar base de datos MySQL en PHP”

Deja el tuyo.

  1. 1

    mintaka:
    Abril 17th, 2008

    hola me ayudo mucho tu clase de php y databases gracias

  2. 2

    Franco:
    Junio 12th, 2008

    Dime esta bacan pero esta clase permite tambien ejecutar insert update y todo eso y si es como podria hacerlo..

  3. 3

    Abel:
    Junio 13th, 2008

    Es fácil:

    $db = DataBase::getInstance();
    $db->setQuery("INSERT INTO tabla VALUES ('','$nombre','$edad')");
    if( $db->alter() ){
        // se inserto...
    }
    else{
        // no se inserto...
    }
    
  4. 4

    Pablo:
    Junio 20th, 2008

    Hola,

    Soy un novato en esto de las clases con PHP, he copiado tal cual tu clase y luego copie en otro php el ejemplo de la consulta, el tema es que me esta dando un error en el foreach:

    Warning: Invalid argument supplied for foreach() in C:\Servidor\Web\pruebaClases\query.php on line 24

    y la linea 24 es la que dice :

    foreach($usuarios as $usuario){

  5. 5

    Abel:
    Junio 20th, 2008

     

    Hola,

    Soy un novato en esto de las clases con PHP, he copiado tal cual tu clase y luego copie en otro php el ejemplo de la consulta, el tema es que me esta dando un error en el foreach:

    Warning: Invalid argument supplied for foreach() in C:\Servidor\Web\pruebaClases\query.php on line 24

    y la linea 24 es la que dice :

    foreach($usuarios as $usuario){

    Supongo que tienes creada una tabla llamada usuarios con esos 3 campos, y que tu tabla tiene más de un registro….

    ¿Verdad?

  6. 6

    Pablo:
    Junio 20th, 2008

    Abel,
    te pido mil disculpas soy tan distraido que me habia olvidado de escribir el nombre de mi base de datos, lo que estoy intentando es agregar los datos de nombre de base, usuario de base, password y servidor para que lo lea de un archivo para que quede parametrizado.

    Te hago una consulta: ¿se usa leer estos datos de un archivo?

    desde ya muchisimas gracias por tu aporte!!!
    Pablo

  7. 7

    Abel:
    Junio 20th, 2008

    No, no se usa leer esos datos de un archivo, pero si asi lo quieres hacer, puedes usar un XML:

    <?xml version="1.0"?>
    	<datos>
    		<host>localhost</host>
    		<usuario>tu_nombre</usuario>
    		<password>tu_password</password>
    		<database>nombre_db</database>
    	</datos>
    

    Solo tendrias que hacerle un parsing, y sacar los datos y usarlos para la conexion… lo cual me parece muy descabellado…. Creo que la mejor alternativa es declarar constantes dentro de la clase y asignarle esos valores…

    Respondi bien tu pregunta o me fui por otro lado?

Deja un comentario

  • Ventana al cosmos

  • Apollo 17: Anaglifo de asientos VIP

  • Publicidad