<?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>Viricmind Labs</title>
	<atom:link href="http://labs.viricmind.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://labs.viricmind.org</link>
	<description>Programando un nuevo mundo</description>
	<lastBuildDate>Sat, 05 May 2012 16:50:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>PHP, sesiones y alta concurrencia</title>
		<link>http://labs.viricmind.org/2012/04/09/php-sesiones-y-alta-concurrencia/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=php-sesiones-y-alta-concurrencia</link>
		<comments>http://labs.viricmind.org/2012/04/09/php-sesiones-y-alta-concurrencia/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 13:44:00 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Desarrollo Web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1256</guid>
		<description><![CDATA[Hoy voy a escribir brevemente sobre cierta problemática asociada al manejo de sesiones en PHP que surge cuando nuestra aplicación web debe soportar un alto nivel de concurrencia. PHP guarda las sesiones en archivos por defecto, aunque hay otros mecanismos posibles: por ejemplo usar bases de datos como MySQL (o bien SQLite), tirar de Memcache, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2012/04/elephpant_281_193.png"><img class="alignleft size-full wp-image-1257" title="Elephpant" src="http://labs.viricmind.org/wp-content/uploads/2012/04/elephpant_281_193.png" alt="" width="281" height="193" /></a>Hoy voy a escribir brevemente sobre cierta problemática asociada al manejo de sesiones en PHP que surge cuando nuestra aplicación web debe soportar un alto nivel de concurrencia.</p>
<p style="text-align: justify;">PHP guarda las sesiones en archivos por defecto, aunque hay otros mecanismos posibles: por ejemplo usar bases de datos como MySQL (o bien SQLite), tirar de Memcache, guardar la información cifrada dentro de cookies, etc.</p>
<p style="text-align: justify;">Ninguno de estos sistemas alternativos está exento de problemas. Las bases de datos al uso añaden una latencia inaceptable en la mayoría de casos, SQLite permite lecturas muy rápidas, pero como contrapartida bloquea la base de datos entera cuando se escribe, Memcache puede sobrecargar nuestra memoria y tiene el riesgo potencial de pérdida de datos por la volatilidad de su sistema de almacenaje, y por último, guardar las sesiones en cookies aumenta ligeramente el riesgo de robo de datos y puede añadir un overhead importante a todas las peticiones HTTP.</p>
<p style="text-align: justify;">¿Y qué pasa con las sesiones en ficheros? Pues también tienen su problemática. Cada petición HTTP llega acompañada de la cookie con el ID de sesión, cuando se llama al método <a href="http://php.net/manual/en/function.session-start.php"><code>session_start</code></a> se abre un descriptor de fichero que guarda la información asociada a la sesión con el ID ya mencionado y... se bloquea el archivo para poder escribir sobre él los cambios que hagamos en las variables de sesión sin que haya conflictos entre peticiones distintas que usan la misma sesión.</p>
<p style="text-align: justify;">El bloqueo que menciono desaparece por defecto en cuanto finaliza la ejecución del script PHP. Esto significa que si en cierto sitio web realizamos (por ejemplo) 5 llamadas AJAX de forma paralela a scripts que hacen uso de la información de sesión, el resultado que obtendremos es una serie de respuestas serializadas en el tiempo, una detrás de otra.</p>
<p style="text-align: justify;">Una solución parcial para conseguir aumentar el nivel de paralelización de las llamadas AJAX (o cualquier otro tipo de petición HTTP) es desbloquear el archivo de sesión lo antes posible, es decir, cuando sepamos que ya no vamos a modificar las variables de sesión y solo vamos a realizar operaciones de lectura. Para ello podemos usar la función <a href="http://php.net/manual/en/function.session-write-close.php"><code>session_write_close</code></a>, en algunos casos se puede conseguir una reducción impresionante de los tiempos de carga, por lo que os recomiendo tenerlo muy en cuenta.</p>
<p style="text-align: justify;">Otro detalle importante: es desaconsejable permitir que PHP inicie la sesión de forma automática (es preferible iniciarla solo cuando sea estrictamente necesario). Si podéis, intentad que la opción <code>session.auto_start</code> esté a false en el fichero de configuración <code>php.ini</code>.</p>
<p style="text-align: justify;">Espero que os haya servido <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2012/04/09/php-sesiones-y-alta-concurrencia/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Enviar archivos mediante HTTP desde PHP</title>
		<link>http://labs.viricmind.org/2012/03/01/enviar-archivos-mediante-http-desde-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=enviar-archivos-mediante-http-desde-php</link>
		<comments>http://labs.viricmind.org/2012/03/01/enviar-archivos-mediante-http-desde-php/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 23:16:31 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Desarrollo Web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[CURL]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Requests]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1221</guid>
		<description><![CDATA[A raíz de mi trabajo en Bananity recientemente he estado trasteando con la subida de archivos al servidor (hasta ese momento nunca había tenido que tratar con eso) y el envío de archivos entre servidores. Y habiéndome parecido interesante lo aprendido estos dos días he creído conveniente comentarlo por aquí . En primer lugar comentaré [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2012/03/filesupload.png"><img class="alignleft size-full wp-image-1222" title="FileUpload" src="http://labs.viricmind.org/wp-content/uploads/2012/03/filesupload.png" alt="" width="200" height="200" /></a>A raíz de mi trabajo en <a title="Bananity" href="http://www.bananity.com">Bananity</a> recientemente he estado trasteando con la subida de archivos al servidor (hasta ese momento nunca había tenido que tratar con eso) y el envío de archivos entre servidores. Y habiéndome parecido interesante lo aprendido estos dos días he creído conveniente comentarlo por aquí <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p style="text-align: justify;">En primer lugar comentaré la parte más típica: cómo hacer un formulario en <a href="http://es.wikipedia.org/wiki/HTML">HTML</a> que permita archivos y como recibir archivos desde <a href="http://es.wikipedia.org/wiki/PHP">PHP</a>.</p>
<p style="text-align: justify;">En segundo lugar comentaré la parte que a mí me ha parecido más interesante (aunque nada complicada): enviar archivos a otros servidores desde PHP.</p>
<h3 style="text-align: justify;">Enviar archivos desde un formulario HTML</h3>
<p style="text-align: justify;">Enviar un archivo a un servidor web desde un formulario HTML es muy sencillo, resumiendo mucho: se tiene que usar el método <code>POST</code>, usar un elemento input de tipo file, y añadir la propiedad <code>enctype</code> al elemento <code>form</code> con el valor <code>"multipart/form-data"</code>. Ejemplo:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="html" style="font-family:monospace;">&lt;form method=&quot;post&quot; enctype=&quot;multipart/form-data&quot; action=&quot;http://sitiodeproceso&quot;&gt;
    &lt;input type=&quot;file&quot; name=&quot;filetoupload&quot;&gt;
    &lt;input type=&quot;submit&quot; value=&quot;Envia!&quot;&gt;
&lt;/form&gt;</pre></td></tr></table></div>

<h3 style="text-align: justify;">Recibir archivos usando PHP</h3>
<p style="text-align: justify;">Muy bien, el visitante de nuestro sitio web ya nos ha enviado su archivo... ¿como lo procesamos para guardarlo? PHP nos provee de unas cuantas variables globales bastante útiles, entre las que se encuentra <a href="http://es.php.net/manual/es/reserved.variables.files.php"><code>$_FILES</code></a>, que es la que utilizaremos. El servidor se encargará de dejar el archivo subido en un directorio temporal, y <code>$_FILES</code> nos dará información sobre su ruta y posibles errores en el proceso de envío.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Notemos que uso como índice el nombre que le dí al elemento input</span>
<span style="color: #666666; font-style: italic;">// en el formulario HTML</span>
<span style="color: #000088;">$fileinfo</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$_FILES</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'filetoupload'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Obtenemos la ruta donde está guardado temporalmente el fichero</span>
<span style="color: #000088;">$filepath</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fileinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'tmp_name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Recuperamos el nombre que tenía el fichero cuando se envió</span>
<span style="color: #000088;">$filename</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$fileinfo</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'name'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Movemos el fichero a donde creamos conveniente</span>
<span style="color: #990000;">move_uploaded_file</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$filepath</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'/ruta/donde/queremos/guardarlo/'</span><span style="color: #339933;">.</span><span style="color: #000088;">$filename</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p style="text-align: justify;">En este ejemplo no he tenido en cuenta la gestión de errores ni otros valores de <code>$_FILES['filetoupload']</code> interesantes como <code>type</code>, <code>error</code> o <code>size</code>.</p>
<h3>Enviar archivos con PHP (1ª opción: CURL)</h3>
<p>Ahora sí, llegamos a la parte que me parecía más interesante <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  , aunque empezaré por la "vía complicada": usar CURL. Este ejemplo lo he extraído de [1].</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
    <span style="color: #000088;">$ch</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_init</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_HEADER<span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_VERBOSE<span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_RETURNTRANSFER<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_USERAGENT<span style="color: #339933;">,</span> <span style="color: #0000ff;">&quot;AgenteQueNosVengaEnGana&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_URL<span style="color: #339933;">,</span> <span style="color: #0000ff;">'http://urlhaciaotroservidor'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_POST<span style="color: #339933;">,</span> <span style="color: #009900; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #666666; font-style: italic;">// Igual que &lt;input type=&quot;file&quot; name=&quot;filetoupload&quot;&gt;</span>
    <span style="color: #666666; font-style: italic;">// Notad la @ antes del path, es clave.</span>
    <span style="color: #000088;">$post</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
        <span style="color: #0000ff;">&quot;filetoupload&quot;</span><span style="color: #339933;">=&gt;</span><span style="color: #0000ff;">&quot;@/path/to/myfile.jpg&quot;</span><span style="color: #339933;">,</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #990000;">curl_setopt</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #339933;">,</span> CURLOPT_POSTFIELDS<span style="color: #339933;">,</span> <span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000088;">$response</span> <span style="color: #339933;">=</span> <span style="color: #990000;">curl_exec</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$ch</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p style="text-align: justify;">La verdad es que puede ser un poco engorroso subir archivos siguiendo este procedimiento, no porque sea mucho código, sino porque se tienen que memorizar (o tener a mano) que parámetros debemos establecer y con que valores.</p>
<p style="text-align: justify;">Evidentemente siempre nos queda la opción de encapsular un código similar a éste dentro de un método, pero a mi este "problema" me servirá como excusa para introducir una solución alternativa <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  .</p>
<h3 style="text-align: justify;">Enviar archivos con PHP (2ª vía: Requests)</h3>
<p style="text-align: justify;">Gracias a mi compañero Carles Iborra descubrí la biblioteca libre <a href="http://requests.ryanmccue.info/">Requests</a>, a la que actualmente estoy dando muchísimo uso, especialmente para realizar testeo unitario, aunque también para enviar archivos usando PHP. El siguiente ejemplo lo dice todo.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #b1b100;">include</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Requests.php'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Requests<span style="color: #339933;">::</span><span style="color: #004000;">register_autoloader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$post</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">'filetoupload'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">'@/path/to/file'</span>
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$request</span> <span style="color: #339933;">=</span> Requests<span style="color: #339933;">::</span><span style="color: #004000;">post</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://dondeenviamoselarchivo'</span><span style="color: #339933;">,</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #000088;">$post</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<h3>Referencias</h3>
<ol>
<li><a href="http://dtbaker.com.au/random-bits/uploading-a-file-using-curl-in-php.html">DTBAKER: Uploading a file using curl in PHP</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2012/03/01/enviar-archivos-mediante-http-desde-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Viendo videos de Youzee en Linux</title>
		<link>http://labs.viricmind.org/2012/02/15/viendo-videos-de-youzee-en-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=viendo-videos-de-youzee-en-linux</link>
		<comments>http://labs.viricmind.org/2012/02/15/viendo-videos-de-youzee-en-linux/#comments</comments>
		<pubDate>Wed, 15 Feb 2012 22:34:32 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[TV]]></category>
		<category><![CDATA[Hulu]]></category>
		<category><![CDATA[Netflix]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Wuaki]]></category>
		<category><![CDATA[Youzee]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1206</guid>
		<description><![CDATA[Para los despistados, Youzee es una nueva plataforma web (creada por iniciativa española, aun en fase beta) para la visualización de películas y series de forma extremadamente cómoda. Eso sí, pagando una cuota de unos 7 € mensuales. A mi parecer, el coste puede valer la pena, el catálogo es grande (y sigue creciendo), la [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2012/02/youzee.png"><img class="alignleft size-full wp-image-1207" title="Youzee Logo" src="http://labs.viricmind.org/wp-content/uploads/2012/02/youzee.png" alt="Youzee Logo" width="200" height="200" /></a>Para los despistados, <a href="http://www.youzee.com">Youzee</a> es una nueva plataforma web (creada por iniciativa española, aun en fase beta) para la visualización de películas y series de forma extremadamente cómoda. Eso sí, pagando una cuota de unos 7 € mensuales. A mi parecer, el coste puede valer la pena, el catálogo es grande (y sigue creciendo), la calidad de streaming es alta y los films y series están disponibles en varios idiomas.</p>
<p style="text-align: justify;">Aunque no es la única plataforma de este estilo (tenemos por ejemplo a <a href="http://www.hulu.com/">Hulu</a>, <a href="http://www.netflix.com">Netflix</a>, que desgraciadamente no aterrizará en nuestro país, u otras iniciativas españolas como <a href="http://www.wuaki.tv">Wuaki.tv</a>) tengo que admitir que hasta el momento es la que más me ha gustado... salvo por un detalle: Hubo problemas con los monitores <a href="http://es.wikipedia.org/wiki/Video_Graphics_Array">VGA</a>, y en especial con Linux (pero tengo la sensación de que lo mismo debe pasar con las otras plataformas estadounidenses).</p>
<p style="text-align: justify;">Por suerte los problemas iniciales se han ido solucionando, y el de Linux se puede sortear con un pequeño apaño. Bastará con instalar el paquete <code>hal</code> con la herramienta <code>aptitude</code> o <code>apt-get</code> (o <code>synaptic</code>, o la que prefiráis vosotros).</p>
<p style="text-align: justify;">Hay un detalle que conviene comentar para los usuarios de Ubuntu. Parece que la forma en que se instala el plugin <a href="http://es.wikipedia.org/wiki/Adobe_Flash_Player">Adobe Flash</a> puede hacer que la cosa funcione o no. En particular recomiendo instalar el paquete <code>adobe-flashplugin</code> en vez del paquete <code>flashplugin-installer</code>. Además es conveniente señalar que la herramienta <code>aptitude</code> puede ser problemática para instalar el paquete <code>adobe-flashplugin</code>, por lo que es preferible usar <code>apt-get</code>.</p>
<h3 style="text-align: justify;">Referencias</h3>
<ol>
<li><a href="http://blog.guiloma.es/2012/01/usando-youzee-en-linuxdebianubuntu.html">http://blog.guiloma.es/2012/01/usando-youzee-en-linuxdebianubuntu.html</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2012/02/15/viendo-videos-de-youzee-en-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Se alínean los planetas para Linux</title>
		<link>http://labs.viricmind.org/2012/02/12/se-alinean-los-planetas-para-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=se-alinean-los-planetas-para-linux</link>
		<comments>http://labs.viricmind.org/2012/02/12/se-alinean-los-planetas-para-linux/#comments</comments>
		<pubDate>Sun, 12 Feb 2012 21:07:40 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Opinión]]></category>
		<category><![CDATA[Sistemas Operativos]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Desura]]></category>
		<category><![CDATA[Gimp]]></category>
		<category><![CDATA[LibreOffice]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1195</guid>
		<description><![CDATA[Este será un breve apunte en el que esbozaré el por qué creo que últimamente le están yendo bien las cosas a todo el mundillo de Linux. La verdad es que últimamente no paro de ver buenos augurios allí donde poso la mirada: parece que los planetas se han alineado para el sistema del pingüino [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2012/02/tux2.jpg"><img class="alignleft size-full wp-image-1197" title="Tux" src="http://labs.viricmind.org/wp-content/uploads/2012/02/tux2.jpg" alt="Tux" width="200" height="200" /></a>Este será un breve apunte en el que esbozaré el por qué creo que últimamente le están yendo bien las cosas a todo el mundillo de <a href="http://es.wikipedia.org/wiki/Distribuci%C3%B3n_Linux">Linux</a>. La verdad es que últimamente no paro de ver buenos augurios allí donde poso la mirada: parece que los planetas se han alineado para el sistema del pingüino <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p style="text-align: justify;">Aunque la noticia ya tiene más de un mes, la usaré como punto inicial de mi argumentación. Hace poco corrió por la red el rumor de que <a href="http://www.muylinux.com/2012/01/04/cuota-de-mercado-linux-2011/">Linux había alcanzado una cuota de mercado del 1.41%</a>, aunque pocos más han vuelto a escribir algo al respecto, un mes después podemos decir que <a href="http://www.netmarketshare.com/report.aspx?qprid=9&amp;qpaf=&amp;qpcustom=Linux&amp;qpcustomb=0">se ha alcanzado el 1.56%</a> (al menos según uno de los muchos <em>barómetros</em> existentes). Aunque soy consciente de que las medidas son falibles y que además hay quienes las contradicen con otros datos, quiero recalcar el hecho de que incluso si los números estuvieran mal, es muy probable que no lo estén tanto las tendencias representadas (en términos cualitativos).</p>
<p style="text-align: justify;">Mi predicción es que la tendencia de crecimiento continuará, <strong>como mínimo</strong>, hasta finales de mayo. Y me apoyo en las siguientes premisas:</p>
<ul>
<li style="text-align: justify;"><a href="es.wikipedia.org/wiki/Ubuntu">Ubuntu</a> 12.04 verá la luz a finales de Abril, lo que generará cierto hype (como siempre sucede), pero esta vez con el añadido de ser una versión LTS (Long Time Support). En el mismo sitio de donde he sacado las estadísticas previas se puede observar un fenómeno similar en el año 2010 (aunque con cifras menores): el uso de Linux creció "rápidamente" en las inmediaciones del lanzamiento de una versión LTS para estancarse un mes después.</li>
<li style="text-align: justify;">El equipo de <a href="http://es.wikipedia.org/wiki/LibreOffice">LibreOffice</a> (que es la suite ofimática por excelencia en Linux) lanzará la versión 3.5 <a href="http://wiki.documentfoundation.org/ReleasePlan/3.5">en breve</a> con <a href="http://wiki.documentfoundation.org/ReleaseNotes/3.5">un montón de mejoras en su rendimiento y nuevas características</a>. El punto clave está en que cada vez hay menos excusas para preferir pagar por MS Office (o arriesgarse a usar versiones pirateadas).</li>
<li style="text-align: justify;">The Gimp lanzará <a href="http://tasktaste.com/projects/Enselic/gimp-2-8">(también en breve</a>, y por fín) su tan esperada versión 2.8. Llegan tarde, pero como mínimo lo han hecho, muchos esperaban que al final todo quedara en agua de borrajas. Además... parece que <a href="http://labs.viricmind.org/2011/08/15/gimp-2-8-a-la-vista-algunas-reflexiones/">se pondrán las pilas para la siguiente versión</a>. Esto lo digo sin olvidar, por supuesto, el valor de otras aplicaciones gráficas como <a href="http://es.wikipedia.org/wiki/Krita">Krita</a>, <a href="http://www.darktable.org/">Darktable</a> o <a href="http://rawtherapee.com/">RawTherapee</a> (que no cesan en su mejora contínua).</li>
<li style="text-align: justify;">Empieza a haber mucha iniciativa en el mundo empresarial para portar aplicaciones a Linux. Como ejemplos tenemos a Spotify (aunque <a href="http://www.spotify.com/es/download/previews/">lo haga todavía sin soporte</a>), Corel (<a href="http://www.omgubuntu.co.uk/2012/01/corel-aftershot-pro-brings-lightroom-competitor-to-linux/">por ejemplo con AfterShot Pro</a>), <a href="http://www.desura.com">Desura</a> (que incluso <a href="http://www.muylinux.com/2012/01/23/desurium-el-cliente-de-desura-ya-es-open-source/">ha abierto el código de su cliente Desurium</a>), las iniciativas de <a href="http://www.humblebundle.com/">The Humble Indie Bundle </a>, juegos de altísima calidad como el nuevo <a href="http://oilrush-game.com/">Oil Rush</a>, etc.</li>
</ul>
<p style="text-align: justify;">Tendremos que esperar para ver si me equivoco o no, a mediados o finales de mayo me podréis dar la vara si he pecado de optimista. Creo que hasta me atreveré a dar números: a finales de Abril se habrá llegado <strong>como mínimo</strong> a un 1.9% de uso (al menos con ese indicador). Para acabar, hay aun un factor que no he considerado todavía ¿qué pasaría si en esta crecida se consigue alcanzar la "masa crítica" que permita alargar el crecimiento unos cuantos meses más?</p>
<p style="text-align: justify;">¿Y vosotros qué opináis?</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2012/02/12/se-alinean-los-planetas-para-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mejorar eficiencia en peticiones AJAX</title>
		<link>http://labs.viricmind.org/2012/02/05/mejorar-eficiencia-en-peticiones-ajax/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mejorar-eficiencia-en-peticiones-ajax</link>
		<comments>http://labs.viricmind.org/2012/02/05/mejorar-eficiencia-en-peticiones-ajax/#comments</comments>
		<pubDate>Sun, 05 Feb 2012 00:02:33 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Desarrollo Web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1171</guid>
		<description><![CDATA[La mayoría de desarrolladores de aplicaciones web desean que éstas sean usadas por miles de personas (y si es a la vez, mejor). Cuando se llega a un determinado número de usuarios, es difícil que la aplicación aguante esa carga si no se han tomado ciertas decisiones. La más simple (y probablemente más cara) pasa [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2012/02/json160.png"><img class="alignleft size-full wp-image-1172" title="JSON logo" src="http://labs.viricmind.org/wp-content/uploads/2012/02/json160.png" alt="JSON logo" width="160" height="160" /></a>La mayoría de desarrolladores de aplicaciones web desean que éstas sean usadas por miles de personas (y si es a la vez, mejor). Cuando se llega a un determinado número de usuarios, es difícil que la aplicación aguante esa carga si no se han tomado ciertas decisiones. La más simple (y probablemente más cara) pasa por añadir más prestaciones a los servidores con los que trabaja nuestra app, pero evidentemente podemos encontrar soluciones ligeramente mejores.</p>
<p style="text-align: justify;">Hoy en día es extraño encontrar una aplicación web que no haga uso de <a href="http://es.wikipedia.org/wiki/AJAX">AJAX</a>, unas lo hacen de manera inteligente y otras no tanto. Vamos a ver qué podemos hacer para reducir un poco(en caso de no haberlo hecho ya) la carga que deben soportar nuestros servidores.</p>
<p style="text-align: justify;">El consejo básico es simple: es preferible que el contenido dinámico sea generado en el lado del cliente con <a href="http://es.wikipedia.org/wiki/JavaScript">Javascript</a> a que el trabajo lo hagan nuestras máquinas. Es claro que no siempre se podrá hacer eso, pero por lo general sí, como ejemplo tenemos datos que se actualizan periódicamente o que se estructuran de forma tabular o en listados.</p>
<p style="text-align: justify;">La justificación del consejo radica en 2 puntos, en primer lugar podemos reducir el tiempo de <a href="http://es.wikipedia.org/wiki/Unidad_central_de_procesamiento">CPU</a> en el servidor consumido por petición, en segundo lugar podemos reducir el ancho de banda usado si enviamos datos como <a href="http://es.wikipedia.org/wiki/JSON">JSON</a> en vez de contenido <a href="http://es.wikipedia.org/wiki/HTML">HTML</a> pregenerado. Así dicho suena creíble, pero tenemos que comprobarlo (me fijaré en el caso concreto de <a href="http://es.wikipedia.org/wiki/PHP">PHP</a>).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Codigo que sirve petición con JSON</span>
<span style="color: #000088;">$link</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xxx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxx'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xxx'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$dbresult</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SELECT nick, passwd, name FROM json'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$outresult</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$outresult</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbresult</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">array_pop</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$outresult</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #990000;">json_encode</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$outresult</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">mysql_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Codigo que sirve la petición con HTML</span>
&nbsp;
<span style="color: #000088;">$link</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xxx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxx'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xxx'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$dbresult</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SELECT nick, passwd, name FROM json'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbresult</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">echo</span> <span style="color: #0000ff;">'&lt;tr&gt;&lt;td&gt;'</span><span style="color: #339933;">,</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'&lt;/td&gt;&lt;td&gt;'</span><span style="color: #339933;">,</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'&lt;/td&gt;&lt;td&gt;'</span><span style="color: #339933;">,</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">'&lt;/td&gt;&lt;/tr&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #990000;">mysql_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Antes de hablar sobre como se procesa la petición en el lado del cliente haré algunas observaciones. Aunque en este código no está, añadí código para medir cuantos milisegundos tardaba cada script en ejecutarse. Para aumentar la fiabilidad de las pruebas conté solo el tiempo que se tarda en procesar el resultado de la consulta a la base de datos y enviarla. Así pues excluyo el acceso a la base de datos y el cierre de la conexión de las medidas efectuadas, que son las siguientes (había 200 registros en la base de datos):</p>
<ul>
<li>Petición servida en JSON (10 muestras):</li>
<ul>
<li>Número de bytes enviados: 18830</li>
<li>Pico de memoria consumida: 305128 bytes ~ 297.976 Kb</li>
<li>Tiempo mínimo: 0.62799 ms</li>
<li>Tiempo máximo: 1.2610 ms</li>
<li>Tiempo medio: 0.9064 ms</li>
<li>Desviación típica: 0.1436 ms</li>
</ul>
<li>Petición servida en HTML (10 muestras):</li>
<ul>
<li>Número de bytes enviados: 23854</li>
<li>Pico de memoria consumida: 100008 bytes ~ 97.664 Kb</li>
<li>Tiempo mínimo: 0.7529 ms</li>
<li>Tiempo máximo: 2.4579 ms</li>
<li>Tiempo medio: 1.2909 ms</li>
<li>Desviación típica: 0.4956 ms</li>
</ul>
</ul>
<p style="text-align: justify;">Lo más destacable de estas medidas es el número de bytes enviados, con JSON podemos ahorrar (como mínimo) un 21.06% de ancho de banda. Digo como mínimo porque en este ejemplo el código HTML generado es más bien austero, ya que no incorpora clases <a href="http://es.wikipedia.org/wiki/Hojas_de_estilo_en_cascada">CSS</a> ni identificadores para facilitar el manejo del <a href="http://es.wikipedia.org/wiki/Document_Object_Model">DOM</a>.</p>
<p style="text-align: justify;">El segundo dato nos muestra la cantidad máxima de memoria consumida durante la petición procesada. Como era esperable, la primera versión del código consume más memoria debido al array que va construyendo y a la cadena JSON que ensambla finalmente a partir de la lista generada. En este punto hay que tener en cuenta que, si somos listos, esto no tiene por qué suponer un gran problema ya que ese mismo array podríamos (y de hecho es recomendable) guardarlo usando (por ejemplo) <a href="http://es.wikipedia.org/wiki/Memcached">Memcached</a> de forma que ahorramos posteriores consultas a la base de datos.</p>
<p style="text-align: justify;">Respecto a los otros datos tengo que decir que no son significativos en lo tocante al asunto JSON vs HTML, pues la comparativa no es del todo justa. Sin embargo, lo que sí podemos ver es qué supone usar repetidas veces la primitiva <em>echo</em> frente a un solo uso. Por un lado aumentan los tiempos de ejecución, y por otro aumenta la dispersión de las medidas (ver desviación típica), lo que puede tocar un poco las narices cuando queremos hacer cálculos de cara a escalar nuestra infraestructura.</p>
<p style="text-align: justify;">Otra versión del código que genera HTML es la siguiente:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$link</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xxx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxx'</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">'xxx'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">mysql_select_db</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'xxx'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$dbresult</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_query</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'SELECT nick, passwd, name FROM json'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000088;">$outresult</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">while</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$row</span> <span style="color: #339933;">=</span> <span style="color: #990000;">mysql_fetch_row</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$dbresult</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000088;">$outresult</span> <span style="color: #339933;">.=</span> <span style="color: #0000ff;">'&lt;tr&gt;&lt;td&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/td&gt;&lt;td&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/td&gt;&lt;td&gt;'</span><span style="color: #339933;">.</span><span style="color: #000088;">$row</span><span style="color: #009900;">&#91;</span><span style="color: #cc66cc;">2</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">'&lt;/td&gt;&lt;/tr&gt;'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #b1b100;">echo</span> <span style="color: #000088;">$outresult</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">mysql_close</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$link</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Los datos que arroja esta versión son los siguientes:</p>
<ul>
<li>Petición servida en HTML (2ª versión, 10 muestras):</li>
<ul>
<li>Número de bytes enviados: 23854</li>
<li>Pico de memoria consumida: 126432 bytes ~ 123.469 Kb</li>
<li>Tiempo mínimo: 0.3531 ms</li>
<li>Tiempo máximo: 0.8111 ms</li>
<li>Tiempo medio:  0.5435 ms</li>
<li>Desviación típica: 0.1577 ms</li>
</ul>
</ul>
<p style="text-align: justify;">Podemos extraer algunas conclusiones más de esta tercera lista de cifras. En primer lugar se nos podría ocurrir adoptar el mismo enfoque para la generación de JSON, es decir, olvidarnos de construir un array y pasar a construir un string directamente (de hecho obtendríamos mejores resultados, pues la cadena JSON es más corta que la cadena HTML). Si no vamos a usar más esos datos en un lapso de tiempo breve parece lo más acertado, pero si tenemos planeado acceder a ellos otra vez puede que sí nos convenga construir la lista como en el primer ejemplo de código.</p>
<p style="text-align: justify;">Un detalle interesante es que teniendo un array probablemente sea más rápido generar un texto JSON con la función <a href="http://es2.php.net/manual/es/function.json-encode.php">json_encode</a> que concatenando strings en un bucle. El problema que tenemos (en este caso) es que el driver nativo de <a href="http://es.wikipedia.org/wiki/MySQL">MySQL</a> para PHP no permite obtener una lista con todas las filas directamente, y consecuentemente nos vemos forzados a construirla nosotros (que es menos eficiente que usar un método nativo de PHP programado en <a href="http://es.wikipedia.org/wiki/C_(lenguaje_de_programación)">C</a>, y de ahí que el tercer ejemplo rinda mejor que el segundo).</p>
<p style="text-align: justify;">Tengo que admitir que no conozco por qué no hay un método nativo de PHP para obtener en forma de array todos los resultados de una consulta a una base de datos MySQL, pero creo que, en caso de no haber razones de peso... puede ser una buena jugada implementar en C una <a href="http://es2.php.net/manual/es/internals2.php">extensión del lenguaje</a> que haga precisamente eso para ahorrar un valioso tiempo de ejecución.</p>
<p style="text-align: justify;">En el lado del cliente las diferencias no han sido estadísticamente significativas para mi ejemplo, aunque es de esperar que los tiempos de descarga sean menores con JSON, mientras que los de proceso sean menores con HTML. El tiempo total dependerá de la potencia de cómputo del cliente y del ancho de banda de la conexión, por lo que algunos usuarios saldrán beneficiados mientras que otros puede que tarden algunos milisegundos más en obtener la página web completamente renderizada.</p>
<p style="text-align: justify;">Sin más rodeos, resumen rápido: JSON permite reducir el ancho de banda consumido en más de un 21%, hacer un solo <em>echo</em> reduce el tiempo de ejecución (la reducción puede sobrepasar fácilmente el 50%, en el caso del ejemplo es un 57.89%) y la dispersión estadística de esos mismos tiempos (lo que nos puede ayudar a realizar mejores cálculos para escalar la plataforma o puede servir para que los balanceadores de carga tengan datos más fiables con los que trabajar).</p>
<p style="text-align: justify;">Como apunte final solo quiero destacar que es importante realizar experimentos y comprobar los hechos por uno mismo, pues la tecnología evoluciona constantemente y es probable que ciertas afirmaciones no se puedan sostener en el tiempo. Además me he dejado algunas técnicas en el tintero, como usar los métodos <a href="http://es2.php.net/manual/es/function.ob-start.php">ob_start</a> y <a href="http://es2.php.net/manual/es/function.ob-end-clean.php">ob_end_clean</a>, que nos permiten aprovechar el buffer de escritura para evitar la necesidad de concatenaciones. Supongo que viendo la extensión del artículo comprenderéis que no lo haya comentado en profundidad. Espero que os haya sido útil <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2012/02/05/mejorar-eficiencia-en-peticiones-ajax/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Como instalar escáner USB en Linux</title>
		<link>http://labs.viricmind.org/2011/12/12/como-instalar-escaner-usb-en-linux/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=como-instalar-escaner-usb-en-linux</link>
		<comments>http://labs.viricmind.org/2011/12/12/como-instalar-escaner-usb-en-linux/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 18:13:36 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Informática]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Drivers]]></category>
		<category><![CDATA[Escáner]]></category>
		<category><![CDATA[Packard Bell]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1141</guid>
		<description><![CDATA[Últimamente Linux ha dado un salto cualitativo en cuanto el soporte que presenta para multitud de dispositivos, incluso es frecuente que todo funcione directamente después de la instalación, sin dar un paso más (cosa que no es tan usual en Windows, donde rara es la vez que no hemos de instalar algún driver). Sin embargo, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2011/12/200px-Gnome-scanner.svg_.png"><img class="alignleft size-full wp-image-1142" title="scanner gnome icon" src="http://labs.viricmind.org/wp-content/uploads/2011/12/200px-Gnome-scanner.svg_.png" alt="" width="200" height="200" /></a>Últimamente Linux ha dado un salto cualitativo en cuanto el soporte que presenta para multitud de dispositivos, incluso es frecuente que todo funcione directamente después de la instalación, sin dar un paso más (cosa que no es tan usual en Windows, donde rara es la vez que no hemos de instalar algún driver).</p>
<p style="text-align: justify;">Sin embargo, como <a href="http://labs.viricmind.org/2011/04/10/canon-impresoras-linux-y-software-libre/">ya apunté</a>, de vez en cuando sucede que hay problemas, y entonces pueden ser bastante gordos. Ayer mismo tuve que ayudar a mi hermano a configurar un escáner (a distancia, yo daba indicaciones), y puedo asegurar que el proceso fue bastante "doloroso" para él. Este tipo de cosas no se le pueden hacer a un newbie. Es por eso que escribo este artículo, para intentar dar unas instrucciones un poco más masticadas que las que encontré y facilitar un poco las cosas a todos aquellos que no saben inglés.</p>
<p style="text-align: justify;">Empecemos, el modelo de escáner de (la novia de) mi hermano es un Packard Bell Diamond 1200 Plus (las instrucciones serán aptas para muchos más modelos) y no está soportado por defecto en Ubuntu 11.10 (así que imaginad el soporte que debe tener en otras distribuciones).</p>
<ol>
<li style="text-align: justify;">El primer paso que deberéis realizar es buscar si vuestro dispositivo está soportado por el proyecto SANE (en la página [2] que enlazo en las referencias). Podréis ver que hay un código de colores que indica qué nivel de soporte tiene el dispositivo. <span style="color: #008000;">Complete</span>, <span style="color: #99cc00;">good</span> o <span style="color: #ff9900;">basic</span> son un buen indicativo, cualquier otra cosa no es buena señal.</li>
<li style="text-align: justify;">Deberemos descargar el fichero de firmware acorde a nuestro escáner. En [1] hay una tabla tal que en su séptima columna (Firmware) están disponibles los enlaces para descargar el fichero correspondiente (la mayoría o todos tienen extensión .usb).</li>
<ul>
<li>
<p style="text-align: justify;">Puede que tengamos un pequeño problema: hay algunos dispositivos diferentes bajo el mismo nombre. Para saber qué archivo debemos descargar, abrimos la línea de comandos y ejecutamos la orden <code>lsusb</code>. Aparecerán una serie de líneas parecidas a esta:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;">Bus 001 Device 002: ID <span style="color: #000000;">8087</span>:0024 Intel Corp. Integrated Rate Matching Hub</pre></td></tr></table></div>

<p style="text-align: justify;">Debemos fijarnos en la línea que haga referencia a nuestro escáner, y mirar los dos números separados por los dos puntos que están detrás de la palabra ID, estos muy probablemente se corresponderán con los números que aparecen en la quinta y sexta columna (VID y PID) y os ayudarán a escoger el fichero adecuado.</p>
</li>
</ul>
<li>
<p style="text-align: justify;">Una vez descargado el fichero pasaremos a trabajar únicamente en la línea de comandos. En primer lugar entraremos como administrador. Dependiendo del sistema deberemos hacerlo con el comando <code>sudo -s</code>, o con el comando <code>su</code>. En segundo lugar, intentaremos crear un nuevo directorio (si ya está creado y recibimos un mensaje de error no pasa nada):</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">mkdir</span> <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>sane<span style="color: #000000; font-weight: bold;">/</span>gt68xx<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

</li>
<li>
<p style="text-align: justify;">Ahora debemos mover el fichero descargado al directorio recién creado (sin olvidar hacerlo como superusuario, en caso contrario el sistema no os dejará hacerlo).</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">cp</span> <span style="color: #000000; font-weight: bold;">/</span>ruta<span style="color: #000000; font-weight: bold;">/</span>al<span style="color: #000000; font-weight: bold;">/</span>fichero<span style="color: #000000; font-weight: bold;">/</span>descargado <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>sane<span style="color: #000000; font-weight: bold;">/</span>gt68xx<span style="color: #000000; font-weight: bold;">/</span></pre></td></tr></table></div>

</li>
<li>
<p style="text-align: justify;">Finalmente, lo único que nos queda es dar permisos de lectura al fichero, y ya habremos acabado <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">chmod</span> a+r <span style="color: #000000; font-weight: bold;">/</span>usr<span style="color: #000000; font-weight: bold;">/</span>share<span style="color: #000000; font-weight: bold;">/</span>sane<span style="color: #000000; font-weight: bold;">/</span>gt68xx<span style="color: #000000; font-weight: bold;">/</span>ficherodescargado</pre></td></tr></table></div>

</li>
</ol>
<p style="text-align: justify;">Espero que os haya resultado útil, para más información podéis visitar las páginas que enlazo en las referencias.</p>
<h3 style="text-align: justify;">Referencias</h3>
<ol>
<li><a href="http://www.meier-geinitz.de/sane/gt68xx-backend/">Instrucciones originales del proyecto SANE</a></li>
<li><a href="http://www.sane-project.org/cgi-bin/driver.pl?manu=&amp;model=&amp;bus=any&amp;v=&amp;p=">Buscador de escáneres soportados por el proyecto SANE</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2011/12/12/como-instalar-escaner-usb-en-linux/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Litipk</title>
		<link>http://labs.viricmind.org/2011/11/18/litipk/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=litipk</link>
		<comments>http://labs.viricmind.org/2011/11/18/litipk/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 22:47:18 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Software Libre]]></category>
		<category><![CDATA[CUSL]]></category>
		<category><![CDATA[Litipk]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1095</guid>
		<description><![CDATA[Este año el Concurso Universitario de Software Libre vuelve a la carga (esta es ya su sexta edición). Yo me presento por enésima vez, a ver si por fin consigo acabar lo que empiezo (sí, quiero acabar, no ganar). El proyecto que presentaré se llama Litipk, y a mi entender será mucho más modesto y [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2011/11/Doodoo.png"><img class="alignleft size-full wp-image-1096" title="Litipk Robot" src="http://labs.viricmind.org/wp-content/uploads/2011/11/Doodoo.png" alt="Litipk Robot" width="250" height="371" /></a>Este año el <a href="http://www.concursosoftwarelibre.org/">Concurso Universitario de Software Libre</a> vuelve a la carga (esta es ya su sexta edición). Yo me presento por enésima vez, a ver si por fin consigo acabar lo que empiezo <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  (sí, quiero acabar, no ganar).</p>
<p style="text-align: justify;">El proyecto que presentaré se llama Litipk, y a mi entender será mucho más modesto y humilde que las barbaridades que "intenté" en las otras ediciones del concurso. Evidentemente eso hace que tenga menos posibilidades de ganar debido a la falta de innovación, pero mi gran propósito es ofrecer algo a la comunidad que pueda empezar a resultar útil a corto plazo.</p>
<h3 style="text-align: justify;">¿Qué "será" Litipk?</h3>
<p style="text-align: justify;">Litipk "será" una aplicación web dirigida a facilitar la búsqueda, catalogación y compartición de material didáctico online, haciendo especial incapié en el aspecto social y comunitario. Mi deseo es conseguir que la gente se ayude mutuamente a la hora de intentar aprender <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<h3 style="text-align: justify;">¿Por qué Litipk?</h3>
<p style="text-align: justify;">Desde hace tiempo la red se está llenando de cursos, tutoriales, vídeos, libros y muchos otros recursos didácticos o formativos. Quien quiere aprender puede hacerlo sin demasiados problemas, pero eso sí, probablemente perderá un tiempo precioso buscando material, tiempo que podría ahorrarse si facilitamos un poco las cosas <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p style="text-align: justify;">Por otro lado, hay un factor importantísimo que me ha motivado a decidirme por este proyecto: la crisis económica. Cada día vemos más recortes en el sector de la educación, ya sea en educación primaria, secundaria obligatoria, bachillerato, formación profesional o las mismas universidades.</p>
<p style="text-align: justify;">Hay muchos potenciales estudiantes que no han podido encontrar plaza allí donde creían oportuno formarse, y otros simplemente no tienen la posibilidad económica de costearse los estudios. Y aunque eso ya debería ser suficiente, pues la educación y la formación tienen valor por sí mismas, es importante destacar también que la economía depende fuertemente de la formación de la ciudadanía. Es por eso que pensé en aportar mi pequeño granito de arena.</p>
<h3 style="text-align: justify;">Algunos apuntes más</h3>
<p style="text-align: justify;">Litipk será desarrollado en CoffeeScript , haciendo uso de NodeJS y una buena lista de librerías y microframeworks libres. Tengo que admitir que a nivel técnico no es una decisión demasiado acertada, es cierto que puedo conseguir resultados espectaculares en cuanto a rendimiento, pero también lo es que trabajaré el doble para conseguir lo que podría hacer con Symfony2 o CakePHP. Sea como sea mi decisión está tomada, y lo que me ha motivado a tomar este rumbo es mi tendencia a probar cosas nuevas <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p style="text-align: justify;">Respecto al blog, esta vez he decidido no crear un blog aparte para el proyecto. Todas las entradas estarán en mi blog personal, Viricmind Labs, pero bajo la etiqueta Litipk. Lo hago así para evitar dispersar demasiado mi atención y poder controlar mejor el histórico de mi trabajo.</p>
<p style="text-align: justify;">Para finalizar, quiero decir también que Litipk ya tiene algo parecido a un logotipo <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  , se trata del robot que podéis ver en este mismo artículo. El dibujo es obra de Cristina Pérez (aunque yo la llamo Pistacho), y está licenciada bajo Creative Commons 3.0 By-Sa .</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2011/11/18/litipk/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Añadir filtro de búsqueda en una tabla con jQuery</title>
		<link>http://labs.viricmind.org/2011/11/11/anadir-filtro-de-busqueda-en-una-tabla-con-jquery/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=anadir-filtro-de-busqueda-en-una-tabla-con-jquery</link>
		<comments>http://labs.viricmind.org/2011/11/11/anadir-filtro-de-busqueda-en-una-tabla-con-jquery/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 17:47:47 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Desarrollo Web]]></category>
		<category><![CDATA[Informática]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1079</guid>
		<description><![CDATA[Para completar el anterior artículo que escribí sobre ordenación de tablas con jQuery [1] hoy os hablaré sobre la creación de un filtro de búsqueda para nuestras tablas, algo prácticamente imprescindible hoy en día en multitud de aplicaciones de gestión que presentan parte de sus datos de forma tabular. El código que veréis a continuación [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2011/11/gnome-system-search.png"><img class="alignleft size-full wp-image-1080" title="Gnome System Search Icon" src="http://labs.viricmind.org/wp-content/uploads/2011/11/gnome-system-search.png" alt="Gnome System Search Icon" width="150" height="150" /></a>Para completar el anterior artículo que escribí sobre ordenación de tablas con jQuery [1] hoy os hablaré sobre la creación de un filtro de búsqueda para nuestras tablas, algo prácticamente imprescindible hoy en día en multitud de aplicaciones de gestión que presentan parte de sus datos de forma tabular.</p>
<p style="text-align: justify;">El código que veréis a continuación es bastante sencillo, no permite búsquedas con operadores lógicos (AND, OR, NOT), ni que se restrinjan a columnas concretas, sin embargo sí que aprovecha toda la potencia de las expresiones regulares para realizar búsquedas relativamente complejas. Para mi gusto es más importante la característica de los operadores lógicos y las restricciones a columnas concretas que la posibilidad de usar expresiones regulares, pero creo que no vale la pena complicar el artículo por algo que no tiene demasiada miga a nivel técnico.</p>
<p style="text-align: justify;">El código es tal que así:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> setup_searchable <span style="color: #009900;">&#40;</span>selector<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> search_input <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#&quot;</span><span style="color: #339933;">+</span>selector<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;-searcher&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	search_input.<span style="color: #660066;">keyup</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #003366; font-weight: bold;">var</span> tbody <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;#&quot;</span><span style="color: #339933;">+</span>selector<span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;-table&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'tbody'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #003366; font-weight: bold;">var</span> hidden_rows <span style="color: #339933;">=</span> tbody.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'tr'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #003366; font-weight: bold;">var</span> searcher <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> search_text <span style="color: #339933;">=</span> search_input.<span style="color: #660066;">val</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toUpperCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			tbody.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			<span style="color: #003366; font-weight: bold;">var</span> shown_rows <span style="color: #339933;">=</span> hidden_rows.<span style="color: #660066;">filter</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				<span style="color: #003366; font-weight: bold;">var</span> re <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> RegExp <span style="color: #009900;">&#40;</span>search_text<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
					 matched <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
&nbsp;
				$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
					matched <span style="color: #339933;">=</span> matched <span style="color: #339933;">||</span> <span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toUpperCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span>re<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
				<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				<span style="color: #000066; font-weight: bold;">return</span> matched<span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
			tbody.<span style="color: #660066;">append</span> <span style="color: #009900;">&#40;</span>shown_rows<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
		<span style="color: #000066; font-weight: bold;">return</span> searcher<span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">En este ejemplo trabajamos con dos elementos básicos, un elemento <code>input</code> de tipo texto y una tabla. El código asume que el selector se referirá a su identificador único <code>id</code>, y que los respectivos ids tendrán una estructura del tipo <em>selector-searcher</em> para el elemento <code>input</code>, y <em>selector-table</em> para la tabla.</p>
<p style="text-align: justify;">Sobre el código, puede ser interesante notar que uso el evento <code>keyup</code> en vez del evento <code>change</code>, esto permite que la tabla se actualice en tiempo real, en contraposición a lo que sucedería con <code style="text-align: justify;">change</code>, que necesita que apretemos la tecla Enter y cambiemos o cambiemos el foco de nuestro cursor. Otro detalle importante es que guardamos en memoria la totalidad de las filas antes de efectuar el filtrado, de modo que evitamos perderlas, y cuando cambiamos los criterios de búsqueda no tenemos que recargar ningún dato desde el servidor. Este último hecho implica que conviene llamar a la función <code>setup_searchable</code> cada vez que recarguemos la tabla con nuevos datos desde el servidor, pues de lo contrario nuestro buscador trabajará con datos "antiguos".</p>
<p style="text-align: justify;">Algunas mejoras obvias para este código aparte de las mencionadas anteriormente serían las siguientes:</p>
<ul>
<li style="text-align: justify;">Posibilidad de trabajar con selectores más generales (lo que puede permitir, por ejemplo, tener dos campos de búsqueda para una misma tabla, uno en la cabecera y otro en el pie).</li>
<li style="text-align: justify;">Añadir un parámetro callback que permita actualizar ciertos datos no mostrados en la tabla en función de lo que haya filtrado nuestra búsqueda. Un ejemplo muy simple sería la actualización de un contador, o en casos más complejos podríamos estar tratando datos como totales, medias, varianzas, etc.</li>
</ul>
<p>Espero que esto le resulte útil a alguien, agradeceré cualquier comentario y propuesta de mejora, saludos! <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<ol>
<li><a href="http://labs.viricmind.org/2011/11/09/ordenacion-de-elementos-del-dom-con-javascript-y-jquery/">Ordenación de elementos del DOM con Javascript y jQuery</a></li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2011/11/11/anadir-filtro-de-busqueda-en-una-tabla-con-jquery/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ordenación de elementos del DOM con Javascript y jQuery</title>
		<link>http://labs.viricmind.org/2011/11/09/ordenacion-de-elementos-del-dom-con-javascript-y-jquery/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ordenacion-de-elementos-del-dom-con-javascript-y-jquery</link>
		<comments>http://labs.viricmind.org/2011/11/09/ordenacion-de-elementos-del-dom-con-javascript-y-jquery/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 18:52:48 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Ciencia]]></category>
		<category><![CDATA[Desarrollo Web]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1056</guid>
		<description><![CDATA[Hace unos días tuve que lidiar con un problema común en el diseño de aplicaciones web: ordenar bajo demanda las filas de una tabla según el valor de una columna concreta. Evidentemente lo primero que hice fue buscar por Internet alguna solución que me permitiera no tener que programar demasiado... y tengo que decir que [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;"><a href="http://labs.viricmind.org/wp-content/uploads/2011/11/Shellsort-edited.png"><img class="alignleft size-full wp-image-1057" title="Shellsort gráfico (from Wikipedia)" src="http://labs.viricmind.org/wp-content/uploads/2011/11/Shellsort-edited.png" alt="Shellsort gráfico (from Wikipedia)" width="280" height="250" /></a>Hace unos días tuve que lidiar con un problema común en el diseño de aplicaciones web: ordenar bajo demanda las filas de una tabla según el valor de una columna concreta. Evidentemente lo primero que hice fue buscar por Internet alguna solución que me permitiera no tener que programar demasiado... y tengo que decir que lo encontré, pero por pequeños detalles nada de eso me sirvió.</p>
<p style="text-align: justify;">Así que en este artículo explicaré el código que acabé picando yo por mi cuenta. Lo que he escrito depende de <a href="http://jquery.com/">jQuery</a>, aunque en realidad se puede sustituir por su "subconjunto" <a href="http://sizzlejs.com/">Sizzle</a>, o incluso por la microbiblioteca <a href="http://zeptojs.com/">Zepto.JS</a> (que tiene una sintaxis compatible con la de jQuery).</p>
<p style="text-align: justify;">Vayamos pues al código directamente, he creado un fichero llamado tablesorter.js en el que está todo el código necesario, salvo la llamada a una función, que se hace allí donde nos convenga <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> row_comparer <span style="color: #009900;">&#40;</span>row1<span style="color: #339933;">,</span> row2<span style="color: #339933;">,</span> index<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> r1 <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>row1<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> index<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toUpperCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> r2 <span style="color: #339933;">=</span> $<span style="color: #009900;">&#40;</span>row2<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'td'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">filter</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
                        <span style="color: #000066; font-weight: bold;">return</span> $<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">index</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">===</span> index<span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toUpperCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">return</span>  <span style="color: #009900;">&#40;</span>r1 <span style="color: #339933;">&gt;</span> r2<span style="color: #009900;">&#41;</span><span style="color: #339933;">?</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">:</span>
	       <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>r1 <span style="color: #339933;">&lt;</span> r2<span style="color: #009900;">&#41;</span><span style="color: #339933;">?-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">:</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> shsort <span style="color: #009900;">&#40;</span>list<span style="color: #339933;">,</span> comparer<span style="color: #339933;">,</span> order<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// Shell sort (with Marcin Ciura's gaps)</span>
	<span style="color: #003366; font-weight: bold;">var</span> gaps <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #CC0000;">701</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">301</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">132</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">57</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">23</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">4</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
	    s <span style="color: #339933;">=</span> list.<span style="color: #660066;">length</span><span style="color: #339933;">,</span>
	    t<span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> k<span style="color: #339933;">=</span><span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> k<span style="color: #339933;">&lt;</span><span style="color: #CC0000;">8</span><span style="color: #339933;">;</span> k<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">// 8 is gaps size</span>
		<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> g <span style="color: #339933;">=</span> gaps<span style="color: #009900;">&#91;</span>k<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> i<span style="color: #339933;">=</span>g<span style="color: #339933;">;</span> i<span style="color: #339933;">&lt;</span>s<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			t <span style="color: #339933;">=</span> list<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> j <span style="color: #339933;">=</span> i<span style="color: #339933;">;</span> j <span style="color: #339933;">&gt;=</span> g <span style="color: #339933;">&amp;&amp;</span> order<span style="color: #339933;">*</span>comparer<span style="color: #009900;">&#40;</span>list<span style="color: #009900;">&#91;</span>j<span style="color: #339933;">-</span>g<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> t<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> j<span style="color: #339933;">-=</span> g<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				list<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> list<span style="color: #009900;">&#91;</span>j <span style="color: #339933;">-</span> g<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			list<span style="color: #009900;">&#91;</span>j<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> t<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
	<span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> sort_table <span style="color: #009900;">&#40;</span>table<span style="color: #339933;">,</span> index<span style="color: #339933;">,</span> order<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #003366; font-weight: bold;">var</span> tbody <span style="color: #339933;">=</span> table.<span style="color: #660066;">find</span> <span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'tbody'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #003366; font-weight: bold;">var</span> rows <span style="color: #339933;">=</span> tbody.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'tr'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #003366; font-weight: bold;">var</span> comparer <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>row1<span style="color: #339933;">,</span> row2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		<span style="color: #000066; font-weight: bold;">return</span> row_comparer <span style="color: #009900;">&#40;</span>row1<span style="color: #339933;">,</span> row2<span style="color: #339933;">,</span> index<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
&nbsp;
	shsort <span style="color: #009900;">&#40;</span>rows<span style="color: #339933;">,</span> comparer<span style="color: #339933;">,</span> order<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
	tbody.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	tbody.<span style="color: #660066;">append</span> <span style="color: #009900;">&#40;</span>rows<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> setup_sortable <span style="color: #009900;">&#40;</span>selector<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
	$<span style="color: #009900;">&#40;</span>selector<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i1<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
		$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">find</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'th'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">each</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span>i2<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> order <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
&nbsp;
			$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">click</span> <span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				sort_table <span style="color: #009900;">&#40;</span>$<span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">closest</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'table'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> i2<span style="color: #339933;">,</span> order<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
				order <span style="color: #339933;">*=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p style="text-align: justify;">Supongo que algunos de los que leéis esto preferiríais que hubiese creado un plugin para jQuery, siento decir que no es así. Eso no es por ninguna razón en particular, simplemente pasa que todavía no me he tomado la molestia de aprender como se hace, y no sé si es complicado o no, supongo que en breve habrá una versión en forma de plugin para jQuery <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  .</p>
<p style="text-align: justify;">En cuanto a como usarlo, la función <code>setup_sortable</code> debe ser llamada utilizando como parámetro un selector para las tablas a las que queramos aplicar ordenación "automática" (con este script las tablas se ordenan cuando se hace click en los elementos <code>th</code> de la tabla, básicamente las cabeceras). En mi caso añadí la clase <code>sortable</code> a todas las tablas que quería añadir esta característica y usé el selector <code>".sortable"</code>.</p>
<p style="text-align: justify;">En cuanto al código, supongo que es destacable que hago un uso intensivo de las funciones anónimas y las clausuras, aunque no es nada que deba sorprender a nadie. En mi humilde opinión, lo más interesante es el algoritmo de ordenación, un "simple" <a href="http://en.wikipedia.org/wiki/Shellsort">Shell sort</a> (basado en <a href="http://en.wikipedia.org/wiki/Insertion_sort">Insertion Sort</a>).</p>
<p style="text-align: justify;">Escogí este algoritmo por las siguientes razones:</p>
<ul>
<li style="text-align: justify;">Es estable, es decir, se mantiene el orden relativo entre elementos con la misma clave (el valor que se usa para realizar las comparaciones) que había en la lista antes de la ordenación. Esto es útil cuando queremos ordenar por distintos criterios a la vez.</li>
<li style="text-align: justify;">Es de fácil implementación, solo tenéis que ver el código. Aquí puede parecer un poco más complicado porque uso la función comparer en vez del típico operador de comparación, pero no es una gran dificultad.</li>
<li style="text-align: justify;">No usa recursión, ni pilas: los requisitos de memoria son pequeños y constantes.</li>
<li style="text-align: justify;">Dependiendo de la implementación (y en particular con esta se consigue), se tiene que para ordenar una lista se deben realizar solo una cantidad de operaciones del orden de O(n·log²(n)).</li>
<li style="text-align: justify;">Se trata de una <em>rara avis</em>, le cogí cariño. Aunque no se trata de un algoritmo destacable por su rendimiento, resulta que es tremendamente complicado a nivel teórico. Tanto que su velocidad depende fuertemente de una serie de parámetros de los que casi no se sabe nada a día de hoy. Yo he usado los de Marcin Ciura, que hasta donde yo sé, son los mejores encontrados hasta el momento.</li>
</ul>
<p>Bien, hasta aquí el apunte de hoy <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  . Espero que os pueda resultar útil, agradeceré cualquier comentario.. y si a alguien le interesa, estoy abierto a aceptar ayuda en la jqueryzación de esta minilibrería. Saludos!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2011/11/09/ordenacion-de-elementos-del-dom-con-javascript-y-jquery/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Peleando con Internet Explorer</title>
		<link>http://labs.viricmind.org/2011/10/27/peleando-con-internet-explorer/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=peleando-con-internet-explorer</link>
		<comments>http://labs.viricmind.org/2011/10/27/peleando-con-internet-explorer/#comments</comments>
		<pubDate>Thu, 27 Oct 2011 22:38:31 +0000</pubDate>
		<dc:creator>castarco</dc:creator>
				<category><![CDATA[Desarrollo Web]]></category>
		<category><![CDATA[Opinión]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://labs.viricmind.org/?p=1046</guid>
		<description><![CDATA[[Actualizado el día 8 de Diciembre de 2011, añadiendo el punto 4] Los que me conocen saben cuanto cariño siento por Internet Explorer, estoy orgulloso de quererlo tanto, y evidentemente no es suficiente para mí que lo sepan mis amigos, quiero gritarlo bien alto. Por eso hoy os brindo este artículo en el que cuento [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_1048" class="wp-caption aligncenter" style="width: 660px"><a href="http://labs.viricmind.org/wp-content/uploads/2011/10/go_out_ie6.png"><img class="size-full wp-image-1048" title="Go Out IE6" src="http://labs.viricmind.org/wp-content/uploads/2011/10/go_out_ie6.png" alt="Go Out IE6" width="650" height="455" /></a><p class="wp-caption-text">IE6 denial message for Momentile.com (by John Martz, CC)</p></div>
<p style="text-align: justify;"><strong>[Actualizado el día 8 de Diciembre de 2011, añadiendo el punto 4]</strong></p>
<p style="text-align: justify;">Los que me conocen saben cuanto cariño siento por Internet Explorer, estoy orgulloso de quererlo tanto, y evidentemente no es suficiente para mí que lo sepan mis amigos, quiero gritarlo bien alto. Por eso hoy os brindo este artículo en el que cuento como darle una buena patada en el culo a este nefasto navegador.</p>
<p style="text-align: justify;">Si más preámbulos, ahí van 3 ungüentos para aliviar el escozor que nos provoca a los desarrolladores:</p>
<ol>
<li style="text-align: justify;"><a href="http://code.google.com/p/ie7-js/">ie7-js</a> : Una(s) librerías que nos ayudan a emular las características de las versiones más nuevas de IE en las más cochambrosas y antiguas. Yo particularmente uso la versión más nueva, ie9-js. Se nota, nos puede ahorrar unas cuantas horas creando horrendos hacks.</li>
<li style="text-align: justify;">Algo más drástico es dar un toque al oficinista cincuentón de turno indicándole que no estaría de más que cambiara su navegador, no es que sea complicado implementar un detector de navegadores... pero si ya está hecho ¿para qué perder el tiempo? <a href="http://www.devslide.com/labs/browser-detection">http://www.devslide.com/labs/browser-detection</a> . Con esta librería podremos mostrar un cuadro de diálogo a nuestro incauto usuario para sugerirle que jubile su viejo talismán antiprogramadores. Consejos respecto a esta librería: yo de vosotros no daría tregua a ninguna versión de IE excepto la 9 (se puede configurar el script para avisar con diferentes navegadores), en mi caso he llegado a modificar un poco el código para que no muestre la opción de descargar IE9 si se está en Windows XP (pues éste no funciona en Windows XP).</li>
<li style="text-align: justify;">Para los listillos de turno que instalaron IE9 y ya no pueden probar sus desarrollos en IE7 o IE8. Cuando se abre IE9, si se apreta la tecla F12 aparece un marco inferior (modo desarrollador) que permite cambiar 2 aspectos del navegador. En primer lugar permite que IE9 renderize las páginas web como si fuera IE7 o IE8, y en segundo lugar también permite engañar a las páginas web cambiando el userAgent, de forma que puedes comprobar también como reaccionan los sitios web con los navegadores IE7 e IE8 <img src='http://labs.viricmind.org/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' />  . Pocas veces diré esto, pero los de Microsoft tuvieron un detallazo implementando esta característica.</li>
<li style="text-align: justify;">Si queremos dar soporte a ciertas características de html5 en Internet Explorer podemos recurrir a <a href="http://code.google.com/p/html5shiv/">htmlshiv</a>. El código de esta librería también lo podemos encontrar integrado en <a href="http://www.modernizr.com/">Modernizr</a> o <a href="http://jquery.com/">jQuery</a> 1.7 .</li>
</ol>
<p style="text-align: justify;">Y ya está, tampoco es que tuviera ninguna panacea, pero algo es algo! Por cierto, el segundo punto lo implementé entre ayer y hoy en una aplicación web que estoy desarrollando. El porcentaje de gente que usa al innombrable en mi aplicación es de un 60% (simplemente acojonante), supongo que en algunos días, o semanas talvez, escribiré un artículo analizando el impacto del aviso. Esperemos que sea efectivo!</p>
]]></content:encoded>
			<wfw:commentRss>http://labs.viricmind.org/2011/10/27/peleando-con-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

