<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Marcos Fernández &#187; General</title>
	<atom:link href="http://www.marcosdev.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.marcosdev.com</link>
	<description>Programación de páginas web</description>
	<lastBuildDate>Mon, 28 Sep 2009 07:59:37 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=abc</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ZCE PHP 5 conseguido</title>
		<link>http://www.marcosdev.com/zce-php-5-conseguido/</link>
		<comments>http://www.marcosdev.com/zce-php-5-conseguido/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 07:57:58 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=75</guid>
		<description><![CDATA[Después de mucho tiempo, vuelvo a postear en mi blog, y en este caso, es para decir que al final, después de una odisea, he conseguido el título de certificación de PHP5 ( Zend Certified Engineer PHP5). Todo ha sido más largo de lo que debería no por no querer presentarme al examen, ya que [...]]]></description>
			<content:encoded><![CDATA[<p>Después de mucho tiempo, vuelvo a postear en mi blog, y en este caso, es para decir que al final, después de una odisea, he conseguido el título de certificación de PHP5 ( Zend Certified Engineer PHP5). Todo ha sido más largo de lo que debería no por no querer presentarme al examen, ya que tenía cita para Julio, si no por que no me dejaron hacerlo. Os resumo mi pequeña odisea:</p>
<ul>
<li>Pido cita (día y hora para hacer el examen a través de la página de Pearson VUE que es la empresa encarga de autorizar centros para la realización del exámen)</li>
<li>Cuadro la cita con mis vacaciones</li>
<li>Dos días antes del examen, repaso y hago exámenes de pruebas (se pueden comprar en la página de Zend)</li>
<li>Me presento en el centro. Me tienen 30 minutos de reloj esperando para al final decirme que no puedo hacer el exámen ya que, según ellos, los de Pearson Vue han cambiado el programa y desde entonces, a ellos no les funcionan por no se cuantas escusas más.</li>
<li>Me traslado a mi pueblo e intento cambiar el examen, pero ya no me dejan por que ya ha pasado.</li>
<li>Tengo que llamar varias veces hasta contactar con Pearson (más vale que habléis inglés si os pasa esto) para realizar la reclamación. Tengo que mandar un e-mail a una dirección determinada.</li>
<li>Mando el e-mail y contactan conmigo dos días después. Hablan con el centro y en teoría en una o dos semanas estará todo arreglado.</li>
<li>Pasan las semanas, mando e-mail sin respuestas hasta que estallo y mando un e-mail acordándome de ciertos parientes. A este e-mail si que recibo respuesta. Intercambio de e-mail con tono tenso.</li>
<li>Busco centro en Madrid (agosto), llamo al centro pero hasta septiembre está cerrado y no me pueden dar información.</li>
<li>Llamo el 2 de septiembre y me comunican que el sistema funciona correctamente y puedo realizar el examen.</li>
<li>Programo viaje para finales de septiembre (y de paso de turismo).</li>
<li>Por fin hago el examen el 25 de septiembre en el centro Azpe de Madrid.</li>
<li>Apruebo!!!!</li>
</ul>
<p>Cómo podéis comprobar, el camino ha sido largo, pero bueno, ya se ha acabado y ahora toca prepararse para el SCJP de Java.</p>
<p>En cuanto al examen, lo que os puedo contar es que es algo más difícil que los de test, principalmente por que aparecen cuestiones referentes a funciones que no están incluidas en el libro de preparación de Apress. No os puedo contar más ya que te hacen firmar que no comentes nada sobre el examen. De todas formas, si os preparáis bien y lleváis bien controlado todo lo que aparece en el libro de Apress, (y mucha práctica, por supuesto), no tendréis problemas para sacaros la certificación.</p>
<p>En cuanto al lugar y forma de realizar el examen, pues lo más resañable sería que cuando lleguéis os verificarán vuestra identidad mediante la solicitación de dos documentos identificativos, luego os pedirán firmar algún documento, iréis a un habitáculo cerrado con cámara, no se puede entrar con ningún objeto personal, ni incluso el reloj. La pantalla del programa de preguntas es toda blanca y podréis revisar todas las preguntas en cualquier momento hasta al hacer clic sobre el botón de evaluar, y por supuesto, todo en inglés.</p>
<p>Espero que más o menos, os haya aclarado un poco la idea del examen.</p>
<p>Un saludo y ánimo a todos</p>
<p>P.D.: aquí os dejo el logotipo con el enlace al perfil mi certificación</p>
<div class="wp-caption alignnone" style="width: 83px"><a href="http://www.zend.com/en/yellow-pages#show-ClientCandidateID=ZEND011172"><img title="ZCF PHP 5" src="http://www.zend.com/img/yellowpages/php5_zce_logo_new.gif" alt="Haz clic en el logo para ver mi perfil" width="73" height="68" /></a><p class="wp-caption-text">Haz clic en el logo para ver mi perfil</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/zce-php-5-conseguido/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Preparando certificación Zend de PHP 5</title>
		<link>http://www.marcosdev.com/preparando-certificacion-zend-de-php-5/</link>
		<comments>http://www.marcosdev.com/preparando-certificacion-zend-de-php-5/#comments</comments>
		<pubDate>Sun, 10 May 2009 10:29:10 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=72</guid>
		<description><![CDATA[Durante estos meses he estado muy ausente del blog. He cambiado de trabajo y  tecnologías con las que tener que programar, y por si fuera poco, también he cambiado de casa, con lo que todo ello conlleva. Además, no se si por el constructor o por telefónica, no tengo línea de ADSL, y estoy con [...]]]></description>
			<content:encoded><![CDATA[<p>Durante estos meses he estado muy ausente del blog. He cambiado de trabajo y  tecnologías con las que tener que programar, y por si fuera poco, también he cambiado de casa, con lo que todo ello conlleva. Además, no se si por el constructor o por telefónica, no tengo línea de ADSL, y estoy con un truñete sistema de internet a través de 3G.</p>
<p>Pero, a lo que iba en este post: <a title="Certificación Zend de PHP" href="http://www.zend.com/en/services/certification/">la certificación Zend de PHP</a>. He comenzado a prepararme seriamente dicha certificación que tenía en mente hace ya mucho tiempo. He comprado el Voucher (ticket para poder hacer el examen) y 5 exámenes de prueba. Tengo previsto realizar la prueba dentro un mes, durante junio probablemente. El examen se puede realizar en cualquier centro Vue autorizado y consiste en 70 preguntas tipo test, multiselección o de escritura, durante un tiempo máximo de 90 minutos. El <a title="Temario Certificación Zend PHP" href="http://www.zend.com/en/services/certification/php-5-certification/">temario</a> intenta contemplar todos los ámbitos de PHP, he incluso diferencias entre la versión 4 y la 5. Una vez superada la prueba, tu perfil aparece en un <a title="Páginas amarillas certificados por Zend" href="http://www.zend.com/en/yellow-pages">listado</a> en la página de Zend, con la gente que ha aprobado el examen, y cuya finalidad es de que si alguna empresa necesita de un programador PHP certificado, pueda ser fácil encontrarlo. Además, te ofrecen colocar un <a title="Logo certificados por Zend" href="http://www.zend.com/services/certification/zce-logo">logo de la certificación</a> enlazado con tu perfil de usuario dentro de Zend. El porcentaje de preguntas aprobadas necesarias para poder aprobar el examen, no lo he encontrado en ningún sitio, así que no puedo dar detalles sobre ese tema.</p>
<p>Dentro de unos días, tengo intención de continuar escribiendo tutoriales que nos ayuden con el día a día, dentro de nuestro mundo de la programación web.</p>
<p>Un saludo</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/preparando-certificacion-zend-de-php-5/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Crear una clase para conectar a la base de datos (IV)</title>
		<link>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iv/</link>
		<comments>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iv/#comments</comments>
		<pubDate>Fri, 21 Nov 2008 08:26:33 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[clases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=57</guid>
		<description><![CDATA[Este va a ser el último tip para ir mejorando nuestra clase. Durante todo el recorrido hemos podido ver una evolución de nuestra clase, ganando abstracción, ganando flexibilidad y ahora vamos a ganar capacidad gestión de errores.

Un problema que podemos tener al trabajar con nuestra base de datos, es que ésta no esté disponible en [...]]]></description>
			<content:encoded><![CDATA[<p>Este va a ser el último tip para ir mejorando nuestra clase. Durante todo el recorrido hemos podido ver una evolución de nuestra clase, ganando abstracción, ganando flexibilidad y ahora vamos a ganar capacidad gestión de errores.</p>
<p><span id="more-57"></span></p>
<p>Un problema que podemos tener al trabajar con nuestra base de datos, es que ésta no esté disponible en un momento determinado por que esté sobrecargada o por que no hay posibilidad de conexión. Por ello, debemos controlar que si no tenemos conexión a la base de datos, la ejecución de nuestra aplicación sea detenida inmediatamente (en el caso de que el uso de la base de datos sea crítico y nuestra aplicación sea 100% dependiente de la conexión a la base de datos.</p>
<p>Existen multitud de formas de controlar y gestionar los errores. PHP nos da ciertas herramientas para intentar capturar estas situaciones. En el ejemplo vamos a utilizar la función <a title="Detalle de la función exit de PHP" href="http://es2.php.net/manual/es/function.exit.php"><em><strong>exit</strong></em></a>, que permite detener inmediatamente la ejecución de nuestro script, y también la función <a title="Detalle de la función error_log de PHP" href="http://es2.php.net/error_log"><em><strong>error_log</strong></em></a> que permite registrar en el log de errores de nuestro servidor web un evento, en nuestro caso, una frase identificadora para que podamos saber cúando ha pasado el problema. Si tenemos un hosting contratado (no un servidor dedicado), es prácticamente seguro que no tendremos acceso al fichero de logs del servidor web, pero lo bueno de esta función es que también es capaz de guardar el registro que nosotros queramos en un derminado fichero o incluso mandar un e-mail a una determinada cuenta. Recomiendo mirar la documentación por que además de las capacidades citadas, permite más opciones, las cuales puedes ser muy útiles para nuestra aplicación.</p>
<p>Lo que vamos a hacer es modificar la función pública conectar() de la clase Db. En dicha función vamos a detectar si nuestra conexión ha fallado, y si se da el caso, registrar dicho error para luego diagnosticar el problema, además de mostrar un error por pantalla avisando al visitante de existe un problema con nuestra aplicación.</p>
<pre>
<pre class="brush: php">
/*Realiza la conexión a la base de datos.*/
private function conectar(){
   switch ($this-&gt;tipo){
      case &#039;mysql&#039;:       $link=mysql_connect($this-&gt;servidor, $this-&gt;usuario, $this-&gt;password);
                          if ($link){
                             mysql_select_db($this-&gt;base_datos,$this-&gt;link);
                             @mysql_query(&quot;SET NAMES &#039;utf8&#039;&quot;);
                          }
                          break;

      case &#039;postgress&#039;:   $this-&gt;link=pg_connect(&quot;host=&quot;.$this-&gt;servidor.&quot; dbname=&quot;.$this-&gt;base_datos.&quot; user=&quot;.$this-&gt;usuario.&quot; password=&quot;.$this-&gt;password)
                          break;
      break;
   }
   if (!$link){
      error_log(0,&#039;Problema de conexión a la base de datos.&#039;);
      exit(&#039;Perdonen las molestias. Tenemos un problema técnico. Esperamos resolverlo en los próximos minutos&#039;);
   }else{
      $this-&gt;link=$link;
   }
}
</pre>
</pre>
<p><a title="Ficheros de ejemplo" href="http://www.marcosdev.com/ejemplos/clase-base-de-datos-iv/archivos.zip">Descargar fichero Db.class.php actualizado (en formato UTF8)</a></p>
<p>Con esto ponemos fin a una pequeña colección de tips. Espero que esto les haya servidor para ir aprendiendo como poder crear y desarrollar una clase, utilizar un patrón de diseño y crear niveles de abastracción.</p>
<p>Temas relacionados:</p>
<p><a title="Crear una clase para conectar a la base de datos" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos/">Crear una clase para conectar a la base de datos</a></p>
<p><a title="Crear una clase para conectar a la base de datos (II)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-ii/">Crear una clase para conectar a la base de datos (II)</a></p>
<p><a title="Crear una clase para conectar a la base de datos (III)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iii/">Crear una clase para conectar a la base de datos (III)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iv/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>Crear una clase para conectar a la base de datos (III)</title>
		<link>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iii/</link>
		<comments>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iii/#comments</comments>
		<pubDate>Tue, 11 Nov 2008 00:23:20 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[clases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=51</guid>
		<description><![CDATA[Continuemos mejorando nuestra clase. En el último tip, creamos una clase nueva para leer un fichero de configuración. Este fichero contenía los valores que nos interesase para realizar la conexión a la base de datos. Luego estuvimos adaptando el fichero de conexión a la base de datos para que fuera capaz de instanciar el objeto [...]]]></description>
			<content:encoded><![CDATA[<p>Continuemos mejorando nuestra clase. En el <a title="Crear una clase para conectar a la base de datos (II)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-ii/">último tip</a>, creamos una clase nueva para leer un fichero de configuración. Este fichero contenía los valores que nos interesase para realizar la conexión a la base de datos. Luego estuvimos adaptando el fichero de conexión a la base de datos para que fuera capaz de instanciar el objeto Conf y pudiera tener acceso a los datos necesarios para realizar la conexión.</p>
<p>En esta siguiente parte del tutorial vamos a realizar una sencilla mejora para hacer que nuestra clase sea capaz de conectarse a diferentes tipos de base de datos. En concreto vamos a ver cómo adaptarla para que se conecte a PostgreSQL.</p>
<p><span id="more-51"></span></p>
<p>Lo primero que debemos realizar es agregar una nueva variable a nuestro fichero de configuración:</p>
<p>config.php</p>
<pre>
<pre class="brush: php">

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

//Servidor
$host=&#039;localhost&#039;;

//Usuario
$user=&#039;user&#039;;

//Password
$password=&#039;test&#039;;

//Base de datos a utilizar
$db=&#039;testDB&#039;;

//Qué sistema gestor de base de datos utilizamos, mysql, oracle, ...
$dbType=&#039;mysql&#039;
</pre>
</pre>
<p>Podemos observar una nueva última variable llamada dbType la cual utilizaremos para saber que tipo de base de datos vamos a utilizar.</p>
<p>Ahora vamos a adaptar nuestra clase Conf para que lea dicho valor y lo guarde ($_dbType). Además agregaremos una función getDBType() para poder obtener dicho valor.</p>
<p>Conf.class.php</p>
<pre>
<pre class="brush: php">
Class Conf{
   private $_domain;
   private $_userdb;
   private $_passdb;
   private $_hostdb;
   private $_db;
   private $_dbType;

   private static $_instance;

   private function __construct(){
      require &#039;config.php&#039;;
      $this-&gt;_domain=$domain;
      $this-&gt;_userdb=$user;
      $this-&gt;_passdb=$password;
      $this-&gt;_hostdb=$host;
      $this-&gt;_db=$db;
      $this-&gt;_dbType=$dbType;
   }

   private function __clone(){ }

   private function __wakeup(){ }

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

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

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

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

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

   public function getDBType(){
	  $var=$this-&gt;_dbType;
	  return $var;
   }

}
</pre>
</pre>
<p>Por último los cambios más significativos vienen dentro de nuestra clase Db. Dentro de las funciones de conectar, ejecutar una query y obtener una fila de resultados es dónde podemos ver cómo en función del  valor tipo de base de datos, la clase utiliza unas funciones u otras.</p>
<p>Db.class.php</p>
<pre>
<pre class="brush: php">

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

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

   private static $_instance;

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

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

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

   private function __wakeup(){ }

   /*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(){
      switch ($this-&gt;tipo){
         case &#039;mysql&#039;:     $this-&gt;link=mysql_connect($this-&gt;servidor, $this-&gt;usuario, $this-&gt;password);
	                   mysql_select_db($this-&gt;base_datos,$this-&gt;link);
	                   @mysql_query(&quot;SET NAMES &#039;utf8&#039;&quot;);
			   break;

       case &#039;postgress&#039;:   $this-&gt;link=pg_connect(&quot;host=&quot;.$this-&gt;servidor.&quot; dbname=&quot;.$this-&gt;base_datos.&quot; user=&quot;.$this-&gt;usuario.&quot; password=&quot;.$this-&gt;password)
		           break;
       break;
      }
   }

   /*Método para ejecutar una sentencia sql*/
   public function ejecutar($sql){
      switch ($this-&gt;tipo){
         case &#039;mysql&#039;:     $this-&gt;stmt=mysql_query($sql,$this-&gt;link);
			   break;
         case &#039;postgress&#039;: $this-&gt;stmt=pg_Euery($this-&gt;link,$sql);
			   break;
         break;
      }
      return $this-&gt;stmt;
   }

   /*Método para obtener una fila de resultados de la sentencia sql*/
   public function obtener_fila($stmt,$fila){
      switch ($this-&gt;tipo){
         case &#039;mysql&#039;:     if ($fila==0){
	                      $this-&gt;array=mysql_fetch_array($stmt);
	                   }else{
	                      mysql_data_seek($stmt,$fila);
	                      $this-&gt;array=mysql_fetch_array($stmt);
	                   }
	                   break;
         case &#039;postgress&#039;: if ($fila==0){
			      $this-&gt;array=pg_fetch_row($stmt);
			   }else{
			      $this-&gt;array=pg_fetch_row($stmt,$fila);
			   }
			   break;
          break;
      }
      return $this-&gt;array;
   }

}
</pre>
</pre>
<p>En el siguiente y última parte, veremos cómo controlar los errores.</p>
<p>Un saludo</p>
<p><a title="Ficheros de ejemplo" href="http://www.marcosdev.com/ejemplos/clase-base-de-datos-iii/archivos.zip">Ficheros del ejemplo (en formato UTF-8)</a></p>
<p>Temas relacionados:</p>
<p><a title="Crear una clase para conectar a la base de datos" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos/">Crear una clase para conectar a la base de datos</a></p>
<p><a title="Crear una clase para conectar a la base de datos (II)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-ii/">Crear una clase para conectar a la base de datos (II)</a></p>
<p><a title="Crear una clase para conectar a la base de datos (IV)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iV/">Crear una clase para conectar a la base de datos (IV)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iii/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Crear una clase para conectar a la base de datos (II)</title>
		<link>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-ii/</link>
		<comments>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-ii/#comments</comments>
		<pubDate>Thu, 06 Nov 2008 08:13:41 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[Base de datos]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[clases]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[singleton]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=41</guid>
		<description><![CDATA[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 como crear una clase, siguiendo también el patrón Singleton, que [...]]]></description>
			<content:encoded><![CDATA[<p><a title="Crear una clase para conectar a la base de datos" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos/">En un post anterior</a> 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.</p>
<p>En en esta segunda parte vamos a ver como 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.</p>
<p><span id="more-41"></span></p>
<p>Lo primero de todo veamos la estructura del fichero de configuración:</p>
<p>config.php</p>
<pre>
<pre class="brush: php">

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

//Servidor
$host=&#039;localhost&#039;;

//Usuario
$user=&#039;user&#039;;

//Password
$password=&#039;test&#039;;

//Base de datos a utilizar
$db=&#039;testDB&#039;;
</pre>
</pre>
<p>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.</p>
<p>Ahora veamos la estructura de la clase Conf</p>
<p>Conf.class.php</p>
<pre>
<pre class="brush: php">
Class Conf{
   private $_domain;
   private $_userdb;
   private $_passdb;
   private $_hostdb;
   private $_db;

   static $_instance;

   private function __construct(){
      require &#039;config.php&#039;;
      $this-&gt;_domain=$domain;
      $this-&gt;_userdb=$user;
      $this-&gt;_passdb=$password;
      $this-&gt;_hostdb=$host;
      $this-&gt;_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-&gt;_userdb;
      return $var;
   }

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

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

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

}
</pre>
</pre>
<p>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:</p>
<pre>
<pre class="brush: php">

/* 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-&gt;setConexion();
      $this-&gt;conectar();
   }

   /*Método para establecer los parámetros de la conexión*/
   private function setConexion(){
      $conf = Conf::getInstance();
      $this-&gt;servidor=$conf-&gt;getHostDB();
      $this-&gt;base_datos=$conf-&gt;getDB();
      $this-&gt;usuario=$conf-&gt;getUserDB();
      $this-&gt;password=$conf-&gt;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-&gt;link=mysql_connect($this-&gt;servidor, $this-&gt;usuario, $this-&gt;password);
      mysql_select_db($this-&gt;base_datos,$this-&gt;link);
      @mysql_query(&quot;SET NAMES &#039;utf8&#039;&quot;);
   }

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

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

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

}
</pre>
</pre>
<p>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.</p>
<p>Veamos que cómo debería quedar el código de ejemplo para que nos funcionase con la nueva clase:</p>
<pre>
<pre class="brush: php">

/*Incluimos el fichero de la clase Db*/
require &#039;Db.class.php&#039;;
/*Incluimos el fichero de la clase Conf*/
require &#039;Conf.class.php&#039;;

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

/*Creamos una query sencilla*/
$sql=&#039;SELECT NOMBRE FROM CLIENTES&#039;;

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

/*Realizamos un bucle para ir obteniendo los resultados*/
while ($x=$bd-&gt;obtener_fila($stmt,0)){
echo $x[&#039;NOMBRE&#039;].&#039;&lt;br /&gt;&#039;;
}
</pre>
</pre>
<p>Cómo 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.</p>
<p>Un saludo</p>
<p><a title="Ficheros de ejemplo" href="www.marcosdev.com/ejemplos/clase-base-de-datos-ii/archivos.zip">Ficheros del ejemplo (en formato UTF-8)</a></p>
<p>Temas relacionados:</p>
<p><a title="Crear una clase para conectar a la base de datos" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos/">Crear una clase para conectar a la base de datos</a></p>
<p><a title="Crear una clase para conectar a la base de datos (III)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iii/">Crear una clase para conectar a la base de datos (III)</a></p>
<p><a title="Crear una clase para conectar a la base de datos (IV)" href="http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-iV/">Crear una clase para conectar a la base de datos (IV)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/crear-una-clase-para-conectar-a-la-base-de-datos-ii/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cargar Google Maps de forma asíncrona</title>
		<link>http://www.marcosdev.com/cargar-google-maps-de-forma-asincrona/</link>
		<comments>http://www.marcosdev.com/cargar-google-maps-de-forma-asincrona/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 18:07:20 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[asíncrona]]></category>
		<category><![CDATA[carga]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[maps]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=31</guid>
		<description><![CDATA[Google Maps ha sido uno de los grandes inventos que se sacó Google de la manga. Normalmente para cargar Google Maps situamos una etiqueta &#60;script&#62; dentro de nuestra página con nuestra id del api de Google Maps. Luego modificamos la etiqueta &#60;body&#62; para que cuando se cargue el documento, ejecute una función para inicializar el [...]]]></description>
			<content:encoded><![CDATA[<p>Google Maps ha sido uno de los grandes inventos que se sacó Google de la manga. Normalmente para cargar Google Maps situamos una etiqueta &lt;script&gt; dentro de nuestra página con nuestra id del api de Google Maps. Luego modificamos la etiqueta &lt;body&gt; para que cuando se cargue el documento, ejecute una función para inicializar el mapa.</p>
<p>El problema que ya comenté en un post anterior (Cargar Google Analytics una vez se haya cargado la página), es que esto, en según que momentos, puede enlentecer de una forma muy grave nuestra página, o por ejemplo, el mapa lo tenemos en una pestaña que por defecto no es visible. Por ello, podemos obtar por una solución que incrementará sustancialmente la velocidad de carga de nuestra página y que se encargará de que, una vez se haya cargado la página, proceder a la descarga y la inicialización del nuestro Google Map.</p>
<p>Esta no es la única utilidad, también podríamos cargar nuestro Google Map a voluntad mediante la pulsación de cualquier elemento. Esto nos permitiría que en una página no cargásemos el Google Map hasta que el usuario decidiese utilizaro, aliviando la carga de nuestra página.</p>
<p><span id="more-31"></span></p>
<p>Veamos un ejemplo práctico llamando a Google Maps una vez se ha terminado la carga de nuestra página:<br />
<a title="Cargar Google Maps al finalizar la carga del resto de la página" href="http://www.marcosdev.com/ejemplos/googlemaps_async/">http://www.marcosdev.com/ejemplos/googlemaps_async/</a></p>
<p>Lo primero de todo, veamos la estructura de nuestros ficheros:</p>
<p><a href="http://www.marcosdev.com/wp-content/imagen-1.png"><img class="aligncenter size-full wp-image-32" title="Estructura de ficheros" src="http://www.marcosdev.com/wp-content/imagen-1.png" alt="" width="160" height="77" /></a></p>
<p>Por un lado tenemos un fichero html en el cual hay una capa que utilizaremos para insertar nuestro Google Maps y las llamadas a los ficheros googleMaps.js y jquery.js.</p>
<pre>
<pre class="brush: html">
&lt; !DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
   &lt;title&gt;Ejemplo de carga de forma asíncrona de Google Maps&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
   &lt;div id=&quot;mapa&quot; style=&quot;width:300px;height: 300px&quot;&gt;
      &lt;p style=&quot;text-align:center&quot;&gt;&lt;strong&gt;Cargando&lt;/strong&gt;&lt;/p&gt;
   &lt;/div&gt;
   &lt;script type=&quot;text/javascript&quot; src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
   &lt;script type=&quot;text/javascript&quot; src=&quot;googleMaps.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</pre>
<p>Cómo podemos ver, el div con id &#8220;<em>mapa</em>&#8221; tiene un texto interior que pone &#8220;Cargando&#8221;. Esto es para que mientras se carga nuestro Google Maps el visitante pueda saber que el navegador está trabajando. Después del div, insertamos las dos llamadas a nuestros ficheros javascript. El primero es la librería jQuery que nos ayudará realizar la petición de carga del conjunto de ficheros necesarios para cargar Google Maps.</p>
<p>En el fichero googleMaps.js tenemos el código necesario para realizar la carga del mapa:</p>
<pre>
<pre class="brush: jscript">
function cargarMapa(){
   if (GBrowserIsCompatible()) {
      var map = new GMap2(document.getElementById(&quot;mapa&quot;));
      map.setCenter(new GLatLng(39.578678,2.646021), 16);
   }
};

$(document).ready(function(){
   var api=&#039;ABQIAAAAOxTvdJxbyGuGB8_UUEe52xRHT0E5MDpBZnfhvo0jhLIefK70hRTYIol4_Lr75EWTtT9VjcaZzY2QWg&#039;;
   $.getScript(&#039;http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=&#039;+api+&#039;&amp;async=2&amp;callback=cargarMapa&#039;);
});
</pre>
</pre>
<p>Lo primero que vemos es una función llamada &#8220;<em>cargarMapa</em>&#8221; la cual será llamada una vez tengamos cargada la librería de Google Maps. Esta función únicamente se encarga de mostrar nuestro Google Maps en un determinado div (en nuestro caso el div llamado &#8220;<em>mapa</em>&#8220;) y situarlo en una coordenada (<em>new GLatLng(39.578678,2.646021)</em>) con un determinado zoom (<em>16</em>).</p>
<p>La parte interesante viene justo después. Vemos el comienzo típico de cualquier fichero js que jQuery ( <em>$(document).ready(function(){</em> ) y justo después dos líneas de código; la primera es una variable en la cual, por cuestiones de tener un código más legible, guardo el clave del api de Google Maps. Y en el segundo realizo la petición, que a simple vista, es la misma url que normalmente nos da google para poner en las etiquetas <em>&lt;script&gt;</em>. Pero si nos fijamos, existe dos diferencias. Justo al final de la línea vemos que hay dos parámetros de url nuevos: <em>&amp;asyn=2&amp;callback=cargarMapa</em>. El primero (<em>async=2</em>) permite llamara de forma asíncrona (cuando nosotros queramos y no siempre cuando se carga el documento al completo), y el segundo (<em>callback=cargarMapa</em>) es el parámetro que le dice a Google Maps que función debe ejecutar una vez tenga todo lo necesario cargado para ser ejecutado.</p>
<p>Ponerlo en práctica es tremendamente sencillo y podemos sacarle mucha utilidad al tema, como por ejemplo, la siguiente demostración dónde cargamos el mapa cuando alguien hace clic sobre un botón:</p>
<p><a title="Cargar Google Maps al hacer clic" href="http://www.marcosdev.com/ejemplos/googlemaps_async/index2.html">http://www.marcosdev.com/ejemplos/googlemaps_async/index2.html</a></p>
<p>La diferencia entre el primer ejemplo y este segundo, reside en que la capa &#8220;mapa&#8221; la tengo escondida y que en vez de cargar el mapa directamente, le agrego una funcionalidad al botón para que este lo carge cuando hagan clic sobre él, y además, haga visible la capa:</p>
<pre>
<pre class="brush: html">
&lt; !DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;
&lt;head&gt;
   &lt;title&gt;Ejemplo de carga de forma asíncrona de Google Maps&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
   &lt;div id=&quot;mapa&quot; style=&quot;width:300px;height:300px;display:none;&quot;&gt;
      &lt;p style=&quot;text-align:center&quot;&gt;&lt;strong&gt;Cargando&lt;/strong&gt;&lt;/p&gt;
   &lt;/div&gt;
   &lt;input type=&quot;button&quot; name=&quot;bCargar&quot; id=&quot;bCargar&quot; value=&quot;Cargar Mapa&quot; /&gt;
   &lt;script type=&quot;text/javascript&quot; src=&quot;jquery.js&quot;&gt;&lt;/script&gt;
   &lt;script type=&quot;text/javascript&quot; src=&quot;googleMaps.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
</pre>
<pre>
<pre class="brush: jscript">
function cargarMapa(){
   if (GBrowserIsCompatible()) {
      var map = new GMap2(document.getElementById(&quot;mapa&quot;));
      map.setCenter(new GLatLng(39.578678,2.646021), 16);
  }
};

$(document).ready(function(){

   //Agregamos evento click al botón
   $(&#039;#bCargar&#039;).click(function(){
      //Mostramos la capa mapa
      $(&#039;#mapa&#039;).show();
      var api=&#039;ABQIAAAAOxTvdJxbyGuGB8_UUEe52xRHT0E5MDpBZnfhvo0jhLIefK70hRTYIol4_Lr75EWTtT9VjcaZzY2QWg&#039;;
      $.getScript(&#039;http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=&#039;+api+&#039;&amp;async=2&amp;callback=cargarMapa&#039;);
   });
});
</pre>
</pre>
<p>Espero que les sea útil</p>
<p>P.D.: Los estilos de la capa &#8220;mapa&#8221; están escritos utilizando el atributo style. Esto no es una buena práctica; hay que utilizar ficheros CSS de estilos. Lo he hecho así para hacerlo más visible para todos.</p>
<p>P.D2.: En el segundo ejemplo se podría insertar la capa &#8220;mapa&#8221; en tiempo real sin necesidad de que esté en el código, pero sería menos didácticos para aquellas personas que tengan un nivel bajo de Javascript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/cargar-google-maps-de-forma-asincrona/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Por fin Myxports</title>
		<link>http://www.marcosdev.com/por-fin-myxports/</link>
		<comments>http://www.marcosdev.com/por-fin-myxports/#comments</comments>
		<pubDate>Fri, 27 Jun 2008 16:18:29 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[myxports]]></category>
		<category><![CDATA[myxports.com]]></category>
		<category><![CDATA[oferta complementaria]]></category>
		<category><![CDATA[portal]]></category>
		<category><![CDATA[turismo]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=10</guid>
		<description><![CDATA[Después de muchísimo trabajo, de duros meses de poco sueño y mucho monitor, por fin ha salido la primera versión de Myxports.com.
Durante estos meses se me ha encargado el objetivo de dar vida a este proyecto. Estoy orgulloso de este proyecto por el cariño que le he puesto, y bajo mi punto de vista, el [...]]]></description>
			<content:encoded><![CDATA[<p>Después de muchísimo trabajo, de duros meses de poco sueño y mucho monitor, por fin ha salido la primera versión de Myxports.com.</p>
<p>Durante estos meses se me ha encargado el objetivo de dar vida a este proyecto. Estoy orgulloso de este proyecto por el cariño que le he puesto, y bajo mi punto de vista, el gran resultado que se ha conseguido. No hemos conseguido tener listo para esta primera versión todas las características que queríamos, pero creo que el resultado ha sido muy bueno.</p>
<p>El portal está desarrollado utilizando las siguientes tecnologías: XHTML Strict 1.0, CSS 2.1, jQuery, PHP 5 y MySQL5.</p>
<p>No me queda más que invitarles a visitar el portal.</p>
<p style="text-align: center;"><a title="Myxports.com" href="http://www.myxports.com"><img class="aligncenter" style="border: 0pt none;" src="http://www.marcosdev.com/imagenes/captura.jpg" alt="Myxports.com" width="421" height="412" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/por-fin-myxports/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SEO: Mejorar la indexación y el posicionamiento en Google</title>
		<link>http://www.marcosdev.com/seo-mejorar-la-indexacion-y-el-posicionamiento-en-google/</link>
		<comments>http://www.marcosdev.com/seo-mejorar-la-indexacion-y-el-posicionamiento-en-google/#comments</comments>
		<pubDate>Sat, 24 May 2008 13:58:39 +0000</pubDate>
		<dc:creator>Marcos Fernández</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[SEO]]></category>

		<guid isPermaLink="false">http://www.marcosdev.com/?p=9</guid>
		<description><![CDATA[Con este pequeño artículo quiero hacer una breve reseña de cómo mejorar la indexación (capacidad de un buscador para rastrear tu web) y el posicionamiento dentro de una búsqueda.

Crea tu página utilizando los estándares. Si cumples con las normas propuestas por el W3C sobre el tipo de documento que quieras utilizar (HTML 4, 5, XHTML [...]]]></description>
			<content:encoded><![CDATA[<p>Con este pequeño artículo quiero hacer una breve reseña de cómo mejorar la indexación (capacidad de un buscador para rastrear tu web) y el posicionamiento dentro de una búsqueda.</p>
<ol>
<li><strong>Crea tu página utilizando los estándares.</strong> Si cumples con las normas propuestas por el <a title="Word Wide Web Consortium" href="http://www.w3.org/">W3C</a> sobre el tipo de documento que quieras utilizar (HTML 4, 5, XHTML 1, 1.1, Transicional o Strict,&#8230;), conseguirás que los buscadores entiendan mejor el contenido y estructura de la página. Además, hacer las páginas cumpliendo los estándares te aseguras que a medida que los navegadores mejoren con este tema, tu página se vea igual en todos los navegadores. Para comprobar que tu código es correcto puedes utilizar el validador de código que pone en nuestras manos la W3C: <a title="Validador W3C" href="http://validator.w3.org/check">http://validator.w3.org/check</a><br />
<span id="more-9"></span></li>
<li><strong>Haz a tu página accesible.</strong> La accesibilidad es la capacidad que tiene tu página para ser utilizada por personas con minusvalías. Es cierto que ha un buscador le va a dar igual si el contraste es alto o no entre la fuente y el fondo, pero no lo que si no le va dar igual es si pones textos alternativos a las imágenes, títulos a los enlaces, documentas la relación de los enlaces con la página que estés creando,&#8230; Una manera fácil de comprobar la accesibilidad de nuestra página, es utilizar este comprobador on-line que podéis encontrar en la siguiente dirección: <a title="Herramienta para analizar la accesibilidad" href="http://www.accesible.com.ar/examinator/">http://www.accesible.com.ar/examinator/</a>. Este validador no asegura que tu página sea accesible al 100% ni mucho menos, pero si que te ayuda a mejorar muchísimas cosas. Además, en el mundo de la accesibilidad hay muchos niveles (<a title="WAI" href="http://www.w3c.es/Traducciones/es/WAI/intro/accessibility">WAI</a>) y para muchas reglas no se pueden utilizar herramientas automáticas.</li>
<li><strong>Reduce el uso de Flash al mínimo</strong>. Los buscadores no son capaces de entender un objeto Flash ni su contenido. Es cierto que Google comienza a leer el contenido de los ficheros Flash y que Adobe cada vez está facilitando la tarea para que esto lo puedan hacer todos los navegadores, pero a día de hoy, la cosa está muy limitada. Además las páginas hechas completamente en Flash no permite copiar la URL de un determinado Producto &#8211; Artículo &#8211; Documento,&#8230; y que una página nos enlace directamente a esa sección y aumentando el PageRank.</li>
<li><strong>Utiliza encabezados</strong> H1, H2, H3..H6. Las etiquetas de encabezado permiten identificar dentro del código que títulos son importantes y además dan información de cual es el orden de importancia. A los buscadores les encanta los encabezados.</li>
<li><strong>Utiliza metatags</strong> para informar sobre el contenido de tus páginas, pero eso si, cuidado que hay metatags que no son estándar y por lo tanto no te van a ayudar.</li>
<li><strong>Los metatags deben ser diferentes en cada página.</strong> No pongas las mismas palabras claves, ni descripción, ni título en todas páginas que componen tu web.</li>
<li><strong>El título es una de las partes más importantes de una web</strong>, normalmente es lo que suele aparecer en los resultados de la búsqueda. No repitas títulos y piénsalos bien utilizando las palabras claves por las cuales quieres que te encuentren.</li>
<li><strong>Haz tus páginas livianas</strong>. Los motores de búsquedas descartan visitar páginas excesivamente pesadas.</li>
<li><strong>Separa la apariencia totalmente de la estructura de la página</strong>. Para crear la estructura de la página se utiliza HTML, para la apariencia se utiliza CSS, para la interactividad Javascript (u otra tecnología). No metas todo en el mismo fichero. Todo bien separadito.</li>
<li><strong>Reduce al máximo el uso de Javascript y Ajax</strong>. Los buscadores no podrán llegar a los contenidos que sólo sean accesibles mediante la utilización de Javascript.</li>
<li>Si tu proyecto precisa de la utilización de Ajax para, por ejemplo, refrescar una lista de resultados de una búsqueda, <strong>haz que esos resultados también sean accesibles de otra forma</strong>, como por ejemplo, una página con un listado, utilización de sitemaps, tanto visuales como en xml.</li>
<li><strong>No utilices enjambres de enlaces</strong> (páginas con miles de enlaces) para conseguir enlaces hacia tu web. Google te penalizará.</li>
<li>Si tu página es dinámica, <strong>haz amigable las URL</strong>. Google si que sabe utilizar más de un parámetro, pero no los tiene bien considerados. El resto de buscadores sufren bastante. Utiliza mod_rewrite para formatear la apariencia de las URL. Esto te beneficia de cara al buscador y al navegante, ya que le parece mucho más clara y fácil de recordar que una URL plagada de variables concatenadas. Ej: http://www.ejemplo.com/producto.php?id=25&amp;cat=5 -&gt; pasaría a ser http://www.ejemplo.com/productos/informatica/25/intel-core-2-duo.</li>
<li><strong>Evita el contenido duplicado</strong>. Hacer la URL amigables es una tarea indispensable, pero tiene un problema congénito: la posibilidad de que infinitas URL lleven al mismo contenido. Si observas el punto anterior, si cambias el texto final inte-core-2-duo por lo que sea, se mostraría el mismo contenido. Esto es un problema. Google puede pensar que estás haciendo algún tipo de spam o que tienes contenido duplicado. Además, dispersas la posibilidad de incrementar el PageRank de esa página en cuestión. Debes poner mecanismos para que si alguien modifica la URL, se autocorriga y vaya a la dirección correcta. (<a href="http://www.ojobuscador.com/2006/01/07/url-canonica-redireccion-301-302/">Redirección</a> 301).</li>
<li><strong>Canoniza la URL</strong>: para google es distinto www.ejemplo.com que ejemplo.com, sin las www. Esto es otro problema de contenido duplicado. Se puede acceder a la misma información con las www que sin ellas. Ya sea por programación o utilizando el fichero .htaccess, debes elegir una forma y obligar que si alguien va a la que tu no has elegido, se cambie automáticamente. Por ejemplo, tu decides que la forma correcta es www.ejemplo.com, pues si alguien escribe en el navegador ejemplo.com, esta dirección debe ser automáticamente remplazada por www.ejemplo.com. (<a href="http://www.ojobuscador.com/2006/01/07/url-canonica-redireccion-301-302/">Redirección</a> 301).</li>
<li><strong>Utiliza las redirecciones</strong>. Si tu proyecto está en marcha y quieres aplicar algunas de las técnicas aquí mencionadas, lo que no debes hacer es eliminar las direcciones antiguas. Lo que debes hacer es que si alguien teclea la dirección de una determinada página la cual tu ahora quieres que se acceda en otra dirección, debes detectar ese comportamiento y mandar una redirección 301. Esto es para intentar que el PageRank que tu viera la página vieja fluctúe hacia la página nueva.</li>
<li>Ten el máximo de <strong>contenido original</strong> posible, es decir, que no esté en otras webs. Una página que escribe su propio contenido, con sus propios textos y además, éste es bastante exclusivo, tendrá mejor PageRank. ¿por qué?, por que Google se ha puesto al día con el tema de los blogs y sabe que muchos copian la misma noticia tal cual. Si tu página está creciendo y tiene poco o nada de PageRank, esto te puede perjudicar mucho. Además, si un visitante observa que en tu página copias / pegas noticias de otros sitios, normalmente se queda con los sitios que ya conocía (Refrán: más vale lo malo conocido que lo bueno por conocer).</li>
<li><strong>Las páginas diseñadas para la impresión pueden producir contenido duplicado</strong>. Muchas veces nos vemos obligados a tener que preparar un página distinta a la página que está viendo el visitante para que se la pueda imprimir. Este caso es muy típico de páginas de venta de productos y de noticias. Si Google entra en estas páginas y considera que puede ser contenido duplicado, os penalizará. Si se accede a través de un enlace html, solventar este problema es tan simple como poner el atributo rel el texto nofollow. Esto le dice a los buscadores que no deben seguir ese enlace y lo deben ignorar.</li>
<li><strong>No realices malas prácticas como mostrar una información distinta si el que te visita es un buscador o un visitante normal.</strong> Si Google lo detecta, te pegará una buena penalización. Pero hecha la regla hecha la trampa. Hay sitios que tienen carta blanca para hacerlo ya que hay una &#8220;justificación&#8221;. Algunos diarios muy grandes no son penalizados por utilizar esta técnica. ¿Por que la utilizan?, son el tipo de medios que debes pagar para ver un contenido, pero si haces la búsqueda aparecen en Google.</li>
<li><strong>Intenta que esté visible todo el texto posible</strong>. Google ya entiende los ficheros CSS y sabe interpretar que un div esté o no visible, que el texto y el color del div sean el mismo, que  tengan ciertas técnicas para camuflar el div, &#8230; Todo esto hará que Google te penalice (en el caso de malas artes) o que no de prioridad a los textos que están ocultos (ya sea por que con javascript iremos mostrándolos, por ejemplo, como pestañas).</li>
<li><strong>Escribe el texto pensando que lo más importante esté en las primeras líneas.</strong> Los buscadores dan prioridades a los textos que van indexando, siendo las primeras líneas las mejor indexadas.</li>
<li><strong>Navega como un buscador.</strong> Intenta ver si eres capaz de navegar por tu página y ver el contenido que tu quieres de la forma que lo vería un Buscador: <a title="SEO Browser" href="http://seobrowser.com">http://seobrowser.com</a>. Esta página te permite ver más o menos como verían tu página los buscadores y te permite ver si se puede navegar o no.</li>
<li><strong>Date de alta en el directorio <a href="http://www.dmoz.org/">dmoz.org</a>. </strong>Es un directorio de webs revisado por humanos, y al principio de los tiempos de los buscadores, éstos lo utilizan bastante. Ahora, su importancia ha bajado mucho, pero todavía tiene su pequeña aportación.</li>
<li><strong>Utiliza las <a title="Herramientas para webmasters de Google" href="https://www.google.com/webmasters/tools/docs/es/about.html">herramientas para webmasters de Google</a>, como Sitemap o Google Analytis</strong>. He comprobado que utilizando la herramienta de estadísticas se acelera el proceso de indexación y además mejora la profundidad.</li>
<li><strong>Calidad de los enlaces</strong>. Ya no es tanto la cuestión de número de enlaces que hay apuntándote hacia tu página, si no de la calidad. Es mucho mejor tener pocos enlaces pero en páginas con pagerank alto. Ese pagerank afectará al pagerank de tu página. Pero también hay que tener en cuenta la temática de los enlaces que apuntan hacia tu página. Si tienes una página tecnológica ¿que hace una página de cocina con enlaces a tu página?.</li>
<li><strong>Edad del dominio</strong>.</li>
<li><strong>Textos escritos con las keywords</strong> (palabras claves) por las que quieres que te encuentren.</li>
<li> <strong>Utiliza la etiqueta &lt;b&gt;&lt;/b&gt;</strong> para resaltar en negrita contenido importante.</li>
<li><strong>No pongas más de 100 enlaces diferentes dentro de la misma página.</strong></li>
<li><strong>Evita URL largas</strong>. Por ejemplo:<br />
- Ejemplo malo: http://www.ejemplo.com/tienda/categoria/subcategoria/producto/25/nombre-producto<br />
- Ejemplo bueno: http://www.ejemplo.com/producto/25/nombre-producto</li>
<li><strong>Sintaxis recomendada para el título</strong>:<br />
Nombreweb | Categoría &gt; Subcategoria &gt; Ítem</li>
<li><strong>Evita el uso de cierto elementos para crear la navegación</strong>:<br />
- Inputs<br />
- Sesiones en la URL<br />
- Páginas restringidas por Cookies<br />
- Frames<br />
- Logins innecesarios.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://www.marcosdev.com/seo-mejorar-la-indexacion-y-el-posicionamiento-en-google/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>
