...Microplagio...

Advertisement

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.

2 Comentarios: