Archive for the ‘mysql’ Category

Crear una clase para conectar a base de datos con PHP

Miércoles, Octubre 29th, 2008

Cuando un programador web comienza con PHP, una de las tareas más habituales es la de realizar conexiones y querys a la base de datos. Normalmente, muchísima gente utiliza funciones php para conectarse a una base de datos directamente en el código como puede ser mysql_connect (para conectarse a una base de datos MySQL) o pg_connect (para conectarse a una base de datos Postgress).

Esta forma de trabajar implica un problema muy serio si nuestro proyecto va orientado a una intranet, en la cual, de la noche a la mañana pueden tener la necesidad de cambiar la base de datos por otra diferente (por ejemplo, que una intranet crezca mucho y necesiten cambiar a una base de datos Oracle por funcionalidades específicas).

Si se da este caso podríamos tener un problema muy grave; deberíamos revisar todo el código que hemos escrito en busca de esas funciones específicas y adaptarlas a la nueva base de datos.

Para solventar este problema (crear una capa que nos abstraiga de que base de datos estemos utilizando) y además crear posibles funcionalidades nuevas, vamos a crear una clase muy sencilla la cual nos permita conectarnos a la base de datos. Esta clase la vamos a crear siguiendo el patrón de diseño Singleton. Los patrones de diseño son soluciones a problemas típicos de programación que se repiten contínuamente. El patrón Singleton nos ayuda a crear una clase la cual, si intentamos llamarla dos veces, realmente sólo es una instancia. En vez intentar crear el objeto, lo que haremos es instanciarlo. Esto nos permite conectarnos a la base de datos en cualquier punto del código (dentro de funciones, dentro de objectos,…) sin necesidad de crear más conexiones o tener que pasarla por parámetro (en el caso de querer que una función determinada que tengamos creada utilice una conexión existente y no cree otra nueva).

La estructura de la clase sería la siguiente:

Código :

<?php

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

   private $servidor='localhost';
   private $usuario='user';
   private $password='test';
   private $base_datos='testDB';
   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->conectar();
   }

   /*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);
   }

}
?>

En esta clase, cómo podemos observar, existen varios métodos para conectar, obtener resultados de una query así como el último id que se ha creado mediante un Insert en un campo clave autoincremental.

Ahora veamos como utilizar esta clase:

Código :

<?php

/*Incluimos el fichero de la clase*/
require 'Db.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 />';
}

?>

Muy sencillo y práctico.

Esta clase es muy (MUY) mejorable. Por ejemplo, en el siguiente tip veremos como utilizar un fichero de configuración que será utilizado por una clase llamada Conf, la cual será utilizada a su vez por esta clase que acabamos de crear. Además, introducir control de errores de conexión, niveles de seguridad para utilizar diferentes perfiles según el ámbito de la conexión,…

Esta clase va dirigida a aquellas personas que todavía no utilizan un Framework y siguen trabajando directamente sobre PHP.

Enviar comentario

Listar resultados de una búsqueda con PHP + MySQL para AJAX

Lunes, Octubre 27th, 2008

Bueno, la idea es realizar un PHP que nos devuelva un XML con resultados de una búsqueda pasada por parámetros POST y lo envíe como text/xml para poder ser recogido de forma fácil mediante JavaScript con el objeto XMLHttpRequest.

Supongamos ahora que tenemos una tabla llamada STOCK en donde almacenamos los registros referidos a cada producto que comercializa la empresa de Manolo. Los principales campos son ID, CÓDIGO DE PRODUCTO, DESCRIPCION, URLIMG (url de la imagen). Vamos a enviarle a nuestro buscador.php la variable buscar por POST para que la recoja en el caso que corresponda y realice la búsqueda.

Veamos un poco de código:

buscador.php

Código :

<?php
   header("Content-type: text/xml");

Antes que nada definiremos el formato de salida como text/xml para que se interprete el contenido como un archivo XML. Esto lo hacemos mediante la función header() que envía una cabecera.

Código :

require (“conexión.php”);

Aquí el archivo con los datos de la conexión a la base de datos, ojo! es muy recomendable que el archivo NO se encuentre en una carpeta pública.

Código :

$condicion = "";
$resultados = 0;

Definimos las variables en juego, $condicion se refiere a la las especificaciones del SELECT de la búsqueda, luego:

Código :

if (isset($_POST['buscar'])) {

      $cadena = htmlentities($_POST['buscar']);
      $cadena = str_replace(" ", "%", $cadena);
      
      $condicion .= " WHERE DESCRIP LIKE '%$cadena%'";
   }

Con htmlentities() prevenimos la inclusión de caracteres no deseados en la consulta. Es importante realizar un control sobre los parámetros pasados para evitar problemas de inyección SQL. Luego reemplazamos los espacios por comodines “%” para especificar que las palabras separadas deben aparecer juntas en los resultados de la búsqueda.

Código :

// REALIZAMOS LA CONSULTA SEGUN LOS PARAMETROS OBTENIDOS   
   $consulta = "SELECT * FROM STOCK$condicion ";
   if (!($res = mysql_query($consulta)))
      echo $consulta;

Así procedemos a realizar la consulta y obtener los resultados, en caso de que la consulta falle devolvemos el código SQL (es importante reemplazar esto por un mensaje de error pertinente).

Y, finalmente, creamos el documento XML mediante el objeto DOMDocument() y funciones como $objeto->appendChild(), $objeto->createElement(), $objeto->setAttribute() que sirven para agregar nodos, crear nodos y setear atributos de un nodo respectivamente, dentro del archivo XML:

Código :

// OBTENEMOS LA CANTIDAD DE RESULTADOS
   $resultados = mysql_num_rows($res);
   
   /** CREAMOS EL DOM DE NUESTRO XML
     * CON LA SIGUIENTE ESTRUCTURA:
      *
     * <productos n=$resultados>
     *       <producto>
     *         <codigo>codigo</codigo>
     *         <descripcion>descripcion</descripcion>
     *          <urlimg>urlimg</urlimg>
     *       </producto>
     *      ...
     * </productos>
     */
   $dom = new DOMDocument('1.0', 'UTF-8');
   $productos =$dom->appendChild($dom->createElement("productos"));
   $productos->setAttribute("n", $resultados);
   
   for ($i=0; $i<mysql_num_rows($res); $i++) {
   
      // DEFINIMOS LAS VARIABLES DE DATOS
      $txtCodigo = utf8_encode(mysql_result($res, $i, 'CODIGO'));
      $txtDescripcion = utf8_encode(mysql_result($res, $i, 'DESCRIP'));
      $txtUrlimg = utf8_encode(mysql_result($res, $i, 'urlimg'));
      
      // ANEXAMOS LOS NODOS
      $producto = $productos->appendChild($dom->createElement('producto'));
      $producto->setAttribute('id', $txtCodigo);
      
      $codigo = $producto->appendChild($dom->createElement('codigo'));
      $codigo->appendChild($dom->createTextNode($txtCodigo));
      
      $descripcion = $producto->appendChild($dom->createElement('descripcion'));
      $descripcion->appendChild($dom->createTextNode($txtDescripcion));
      
      $urlimg = $producto->appendChild($dom->createElement('urlimg'));
      $urlimg->appendChild($dom->createTextNode($txtUrlimg));
   }

Y, por último, devolvemos el resultado como un XML de la siguiente forma:

Código :

// UNA VEZ CREADO EL XML LO VOLCAMOS EN LA PANTALLA
   $dom->formatOutput = true;
   echo $dom->saveXML();
      
   mysql_close();
?>

Eso es todo, es bastante simple y provee un punto de partida para facilitar el trabajo con el lenguaje de servidor en AJAX y realizar un nexo entre los registros de una base de datos con la aplicación correspondiente, espero haya servido, saludos!

Enviar comentario