Identifícate...

...o regístrate

codeando.net

mié, 26 nov 2008 - Archivado en PHP, Tutoriales y Bases de datos

Hola de nuevo, hoy vamos a comenzar una clase de artículos en los que crearemos una librería de abstracción de bases de datos ¿que qué es eso? pues vamos a verlo.

De entrada, una capa de abstracción de bases de datos, nos permitirá cambiar el motor de la base de datos, de forma fácil y sencilla, de forma que la aplicación continúe funcionando de forma normal y sin efectuar ningún cambio en ella. Esto significa, que también podremos desarrollar aplicaciones que trabajen contra cualquier motor de bases de datos, sin cambiar nuestra sintaxis ni las funciones a utilizar.

Además, podemos implementar métodos para realizar selects, inserts, updates y deletes, entre otros, con lo que nuestro código podría quedar limpio de sentencias SQL (personalmente, es una práctica que prefiero no usar; a mí me es muy útil leer mis sentencias SQL de forma literal, pero para gustos... colores)

Bueno, pongámonos manos a la obra, lo primero que debemos hacer es crear la clase y establecer una conexión con la base de datos:

class MyDBLayer {
 
	private $db = '';				// Base de datos.
	private $host = 'localhost';	// Servidor.
	private $user = 'user';			// Usuario.
	private $password = 'password';	// Password.
 
	public $handler = null;			// Handler de la conexión.
 
	private $engine = 'mysql';		// Motor de base de datos.
	private $autoconnect = false;	// Indica si debemos autoconectar al crear el objeto.
	private $connected = false;		// Indica si estamos conectados.
	private $queries = array();		// Contiene los queries ejecutados.
 
	public function __construct( $db, $host, $user = '', $password = '', $connect = false, $engine = 'mysql' ) {
 
		//
		// Inicializamos variables
		//
		$this->db = $db;
		$this->host = $host;
		if (strpos($host,'@') !== false) {
			$tmp = explode( '@', $host );
			$this->host = $tmp[0];
			$this->user = $tmp[1];
			if (count($tmp) > 2) {
				$this->password = $tmp[2];
			}
			if (count($tmp) > 3) {
				$this->autoconnect = (in_array($tmp[4],array('yes','true','1') ? true : false;
			}
		} else if (is_array($host)) {
			$this->host = $host[0];
			$this->user = $host[1];
			$this->password = $host[2];
			if (count($host) > 3) {
				$this->autoconnect = (in_array($host[4],array('yes','true','1') ? true : false;
			}
		} else {
			$this->user = $user;
			$this->password = $password;
			$this->autoconnect = $connect;
		}
 
		if ($engine != 'mysql') $this->engine = $engine;
 
		if ($this->autoconnect) {	// Si debemos conectar al inicio lo hacemos...
			$this->connect();
		}
 
	}
 
	public function connect() {
 
		if ($this->engine == 'mysql') {
			$this->handler = @mysql_connect( $this->host, $this->user, $this->password );
		}
 
		if ($this->handler) {
			if (!mysql_select_db($this->db, $this->handler)) {
				$this->errors[] = 'Error de selección de base de datos: ' . mysql_error();
				return false;
			}
			$this->connected = true;
			return true;
		} else {
			$this->errors[] = 'Error de conexión con el servidor: ' . mysql_error();
			return false;
		}
 
	}
  

Bien, como vereis, el constructor lo hemos montado de forma que sea capaz de recibir los parámetros de distintas formas: le podemos pasar los parámetros de forma tradicional o podemos agrupar los parámetros de conexión en el parámetro $host, ya sea como una cadena con el caracter "@" como separador (ej: host@usuario@password[@autoconectar[@motor]]) o como un array numérico, mantiendo el mismo orden de parámetros (host, usuario, password, autoconectar y motor) y una vez ha establecido las propiedades base de la clase, es capaz de realizar la conexión llamando a la función "connect", si se lo especificamos, claro.

En la función "connect", realizamos la conexión al servidor y seleccionamos la base de datos, comprobando el motor seleccionado, lo que nos da la posibilidad de extender nuestra clase para que sea capaz de trabajar sobre cualquier motor, ya sea mysql, postgre, mssql, odbc, etc...

Y para acabar con la primera entrega de esta serie, vamos a darle un poco de funcionalidad a la clase, implementando los métodos necesarios para extraer datos:

public function query( $sql, $query = 'main' ) {
 
	if (!$this->connected) {		// Comprobamos si estamos conectados, si no lo hacemos.
		$this->connect();
	}
 
	if ($this->connected) {
 
		if ($this->engine == 'mysql') {
 
			//
			// Realizamos el query y almacenamos el resultado en el array "queries"
			//
			$this->queries[$query]['query'] = $sql;
			$this->queries[$query]['result'] = mysql_query( $this->queries[$query]['query'], $this->db ) || $this->SendError();
 
			if ($this->queries[$query]['result']) {
 
				//
				// Si el query ha tenido éxito, extraemos información del resultado.
				//
				$this->queries[$query]['recno'] = 0;
 
				if ((substr( strtoupper(trim($this->queries[$query]['query'])), 0, 6 ) == "SELECT") || (substr( strtoupper(trim($this->queries[$query]['query'])), 0, 7 ) == "EXPLAIN") || (substr( strtoupper(trim($this->queries[$query]['query'])), 0, 4 ) == "SHOW")) {
 
					$this->queries[$index]['numfields'] = mysql_num_fields( $this->queries[$index]['result'] );
					$this->queries[$index]['numrows']   = mysql_num_rows( $this->queries[$index]['result'] );
 
					for ($ct=0;$ct<$this->queries[$index]['numfields'];$ct++) {
						$this->queries[$index]['fields'][$ct]['name'] = mysql_field_name( $this->result, $ct );
						$this->queries[$index]['fields'][$ct]['type'] = mysql_field_type( $this->result, $ct );
						$this->queries[$index]['fields'][$ct]['size'] = mysql_field_len( $this->result, $ct );
					}
 
				}
 
			}
 
			return $this->queries[$index]['result'];
 
		}
 
	}
 
}
 
public function get( $row, $col, $query = 'main' ) {
 
	$return = false;
 
	if ($this->engine == "mysql") {
		$return = mysql_result( $this->queries[$query]['result'], $row, $col );
	}
 
	return $return;
 
}

Como se puede observar, el método "query" realiza una consulta sobre la base de datos y la almacena en un array con un índice definido por nosotros, o usando uno por defecto. Además, si la consulta debe devolver resultados (es decir, no es un UPDATE ni un INSERT) extrae y almacena información sobre el resultado, como número de registros o número de campos, así como el nombre, tipo y tamaño de los mismos.

El método "get", símplemente extrae y devuelve un valor del resultado de cualquiera de las consultas realizadas o false si hay algún error.

Y aquí terminamos la entrega de hoy, en las siguientes iremos implementando nuevos métodos de acceso a datos y agregaremos nuevos motores de bases de datos a nuestra clase.

Por Jose. Han entrado 9412 veces. Hay 5 comentarios       
jue, 20 nov 2008 - Archivado en Otros

Pues si, lo odio, hoy he estado pensando un poco acerca de el, y de lo que podía hacer con mi Nokia 8310 (nada). Me mensajeaba con mis amigos, hacia las llamadas que tenia que hacer y solo las justas por que constaban un congo..... 

Por el contrario hoy puedo hacer de todo, mi N95 es un pequeño disco duro, tiene 8G que funcionan como si fuese un lápiz de memoria,es un walkman a lo bestia, las nuevas generaciones ya no aprenderán ni las letras de las canciones, antes teníamos que oír la misma puñetera cinta hasta que se daba de si y se oía como si el que cantaba estuviese en la montaña rusa, tengo un GPS integrado, por lo que ya no me aprendo el nombre de una p. calle, ni presto atención a los caminos y casi casi ni miro la carretera, tengo una conexión permanente a San Google, con lo que cualquier duda cultural, social o moral es consultada en el instante, por lo que no voy a aprender nada de nada por que tardo menos en mirarlo que en recordarlo, y ya puestos no me voy a aprender ni los nombres de mis amigos por que cuando me llaman ademas de salir su nombre les veo el careto, hago fotos y bla bla, bla bla. Resultado, la cojo batería de mi super N95-8G de 1200mA me dura en pleno rendimiento 1.5h aprox.

Seguir leyendo...

Por mquinteiro. Han entrado 4890 veces. Hay 4 comentarios       
vie, 07 nov 2008 - Archivado en (X)HTML, CSS, Diseño y Tutoriales

Uno de los elementos clave en una página web es el menú de navegación. Hay muchos factores que influyen en el diseño de un menú, pero ante todo:

  • Debe ser bien visible a primera vista.
  • Debe ser claro.
  • Ha de estar bien formado y ser accesible.
  • Debe cumplir los estándares del W3C.

Bien, para construir nuestro menú, primero crearemos la estructura, usando una lista desordenada (<ul>). Muchos de vosotros direis ¿porqué todo el mundo se empeña en que tengo que utilizar listas para construir un menu? La respuesta es bien sencilla: el XHTML es un lenguaje diseñado para estructurar datos, y un menú no deja de ser una lista de enlaces, por lo que lo más natural sería representarlo como lo que es, una lista.

Como ejemplo real, cogeré una web que desarrollé hace poco, www.almirantelibros.com. Lo primero, como decíamos es crear la estructura del menú:

  1. <ul id="lmenu">
  2. <li id="lmenu1"><span class="selected">Inicio</span></li>
  3. <li id="lmenu2"><a href="http://www.almirantelibros.com/almirante/">Quienes somos</a></li>
  4. <li id="lmenu3"><a href="http://www.almirantelibros.com/coleccion/">La colecci&oacute;n</a></li>
  5. <li id="lmenu4"><a href="http://www.almirantelibros.com/blog/">El Blog</a></li>
  6. <li id="lmenu5"><a href="http://www.almirantelibros.com/noticias/">Noticias</a></li>
  7. <li id="lmenu6"><a href="http://www.almirantelibros.com/contacto/">Contacto</a></li>
  8. </ul>

Esto nos daría como resultado algo parecido a lo siguiente:

Ya tenemos un menú que, aunque completamente funcional, necesita que le demos forma, lo cual haremos a continuación utilizando CSS y una imagen que habremos preparado previamente. Lo primero es preparar la lista para mostrarla de forma horizontal:

  1. ul#lmenu {
  2. padding: 0;
  3. margin: 0;
  4. }
  5.  
  6. ul#lmenu li {
  7. list-style-type: none; /* Eliminamos el punto de los elementos de la lista */
  8. float: left; /* Con esta línea ya tenemos el menú en horizontal */
  9. height: 38px; /* Establecemos el alto, para adaptarlo a la imagen */
  10. }

Una vez tenemos el menú en horizontal, cargaremos la imagen del menú, y digo "la imagen" porque utilizaremos una técnica llamada "CSS Sprites" que ya revisaremos a fondo, y que consiste en cargar una sola imagen como si fuera un "mapa" con todas las imágenes que vamos a utilizar, en este caso en el menú:

 

 Y ahora vamos con el código CSS:

  1. ul#lmenu li a,
  2. ul#lmenu li span {
  3. display: block; /* Convertimos los enlaces y el "span" en bloques */
  4. background-image: url(/images/menu.jpg); /* Les asignamos a todos la misma imagen, así sólo la cargamos una vez */
  5. background-repeat: no-repeat;
  6. text-indent: -24000px; /* Escondemos el texto, indentándolo fuera de la página hacia la izquierda */
  7. }
  8.  
  9. /* A continuación, con "background-position" y "width", posicionamos la imagen de fondo para cada elemento del menú */
  10.  
  11. li#lmenu1 a {
  12. background-position: left 1px;
  13. width: 72px;
  14. }
  15.  
  16. li#lmenu1 a:hover {
  17. background-position: left -37px;
  18. }
  19.  
  20. li#lmenu1 span {
  21. background-position: left -75px;
  22. width: 72px;
  23. }
  24.  
  25. li#lmenu2 a {
  26. background-position: -100px 1px;
  27. width: 166px;
  28. }
  29.  
  30. li#lmenu2 a:hover {
  31. background-position: -100px -37px
  32. }
  33.  
  34. li#lmenu2 span {
  35. background-position: -100px -75px;
  36. width: 166px;
  37. }
  38.  
  39. li#lmenu3 a {
  40. background-position: -292px 1px;
  41. width: 105px;
  42. }
  43.  
  44. li#lmenu3 a:hover {
  45. background-position: -292px -37px
  46. }
  47.  
  48. li#lmenu3 span {
  49. background-position: -292px -75px;
  50. width: 105px;
  51. }
  52.  
  53. li#lmenu4 a {
  54. background-position: -423px 1px;
  55. width: 78px;
  56. }
  57.  
  58. li#lmenu4 a:hover {
  59. background-position: -423px -37px
  60. }
  61.  
  62. li#lmenu4 span {
  63. background-position: -423px -75px;
  64. width: 78px;
  65. }
  66.  
  67. li#lmenu5 a {
  68. background-position: -528px 1px;
  69. width: 92px;
  70. }
  71.  
  72. li#lmenu5 a:hover {
  73. background-position: -528px -37px
  74. }
  75.  
  76. li#lmenu5 span {
  77. background-position: -528px -75px;
  78. width: 92px;
  79. }
  80.  
  81. li#lmenu6 a {
  82. background-position: -645px 1px;
  83. width: 105px;
  84. }
  85.  
  86. li#lmenu6 a:hover {
  87. background-position: -645px -37px
  88. }
  89.  
  90. li#lmenu6 span {
  91. background-position: -645px -75px;
  92. width: 105px;
  93. }

Y con esto, ya tenemos terminado el menú, el ejemplo lo teneis en: www.almirantelibros.com

Por Jose. Han entrado 6241 veces.  Comentarios
mié, 05 nov 2008 - Archivado en PHP, Javascript y Tutoriales

Sigamos con el ejercicio que empezamos la semana pasada, hoy vamos a retocar el ejemplo para que nuestro script no nos muestre las etiquetas ya seleccionadas. Para ello, modificaremos las opciones del plugin "autocomplete" para que envíe el contenido ya seleccionado a nuestro script PHP, quedando así nuestro código en javascript:

  1. <script type="text/javascript"><!--
  2. $().ready(function(){
  3. $("#tags").autocomplete('gettags.php', { multiple: true, cacheLength: 0, autoFill: true, selectFirst: true, extraParams: { t: function() { return $("#tags").val() } }, formatItem: formatItem, formatResult: formatResult } );
  4. });
  5. function formatItem(row) {
  6. return row[0] + " (" + row[1] + ")";
  7. }
  8. function formatResult(row) {
  9. return row[0];
  10. }
  11. --></script>

Como vereis, hemos añadido un nuevo parámetro en la llamada a la función autocomplete:

extraParams: { t: function() { return $("#tags").val() } }

Con esto, hacemos que el plugin entregue el valor del campo "#tags" en el parámetro "t" en cada llamada (para que esto funcione, debemos también desactivar la caché con el parámetro: cacheLength: 0) el cual utilizaremos para crear un filtro en nuestra sentencia SQL:

  1. <?php
  2.  
  3. $db = mysql_connect( 'localhost', 'user', 'password' );
  4. mysql_select_db( 'my_db', $db );
  5. if ($_GET['t'] > '') {
  6. $filter = ' AND tag NOT IN ("' . str_replace( ', ', '", "', $_GET['t'] ) . '")';
  7. } else {
  8. $filter = '';
  9. }
  10. $result = mysql_query( 'SELECT tag, COUNT(tag) FROM blogs_arts_tags WHERE tag LIKE "' . $_GET['q'] . '%"' . $filter . ' GROUP BY tag ORDER BY tag', $db );
  11. while ($row = mysql_fetch_row( $result )) {
  12. echo $row[0], "|", $row[1], "\n";
  13. }
  14.  
  15. ?>

Y ya lo tenemos, podéis volver a pasar por la página de demostración para comprobar su funcionamiento, espero que lo disfrutéis ;)

Ver demostración.

Por Jose. Han entrado 5456 veces. Hay 1 comentario       
lun, 03 nov 2008 - Archivado en Enlaces y Diseño

Me he encontrado en Smashing Magazine con una estupenda librería de iconos sobre gráficos.

Disfrutadla.

Por Jose. Han entrado 5456 veces.  Comentarios