<?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>TecnoRetales &#187; PHP</title>
	<atom:link href="http://www.tecnoretales.com/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.tecnoretales.com</link>
	<description>La experiencia no se olvida</description>
	<lastBuildDate>Mon, 13 Sep 2010 21:37:21 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; float: right; padding-right: 0; margin: 3px;"><!-- Ad number: 1 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Error con setlocale()&#8230; devuelve false</title>
		<link>http://www.tecnoretales.com/programacion/setlocale-devuelve-false/</link>
		<comments>http://www.tecnoretales.com/programacion/setlocale-devuelve-false/#comments</comments>
		<pubDate>Mon, 13 Sep 2010 21:36:34 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=768</guid>
		<description><![CDATA[Los usuarios de Ubuntu, pueden encontrarse con un problema al hacer una llamada a la función setlocale() encargada de asignar el idioma correcto para, por ejemplo, llamar a la función getText() y que recoja las traducciones en el idioma correcto.
El problema está en que únicamente podemos cargar los idiomas que están presentes en el sistema [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-770" src="http://www.tecnoretales.com/wp-content/uploads/2010/09/i18n.png" alt="i18n" width="128" height="128" />Los usuarios de Ubuntu, pueden encontrarse con un problema al hacer una llamada a la función setlocale() encargada de asignar el idioma correcto para, por ejemplo, llamar a la función getText() y que recoja las traducciones en el idioma correcto.</p>
<p>El problema está en que únicamente podemos cargar los idiomas que están presentes en el sistema operativo y si intentamos cargar uno diferente, <em>setlocale</em>() nos devolverá siempre <em>false</em>.</p>
<p>Podemos saber los idiomas cargados en el sistema operativo mediante el comando:</p>
<blockquote><p><strong>locale -a</strong></p></blockquote>
<p>Esto nos devolverá un listado similar a este:</p>
<blockquote><p><strong>C<br />
en_GB.utf8<br />
en_IN<br />
en_NG<br />
en_US.utf8<br />
POSIX</strong></p></blockquote>
<p>Si estámos intentando cargar el idioma es_ES (como era mi caso), le resultará imposible&#8230; la solución, instalar los idiomas que necesitamos lanzando el comando:</p>
<blockquote><p>apt-get install language-pack-es-base</p></blockquote>
<p>Posteriormente, reiniciaremos Apache:</p>
<blockquote><p>/etc/init.d/apache2 reload</p></blockquote>
<p>Y le indicaremos a nuestro programa que cargue el idioma con el mismo nombre que lo encontramos en nuestro sistema, es decir, en mi caso:</p>
<blockquote><p>setlocale( LC_MESSAGES, &#8220;es_ES.UTF8&#8243; );</p></blockquote>
<p>Y con esto conseguiremos que nuestro programa quede internacionalizado de manera correcta.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/setlocale-devuelve-false/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pasar segundos a horas:minutos:segundos</title>
		<link>http://www.tecnoretales.com/programacion/pasar-segundos-a-horas-minutos-segundos/</link>
		<comments>http://www.tecnoretales.com/programacion/pasar-segundos-a-horas-minutos-segundos/#comments</comments>
		<pubDate>Thu, 05 Nov 2009 21:34:31 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Script]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=711</guid>
		<description><![CDATA[Una sencilla función que dado un número de segundos, nos devuelve el tiempo en formato hh:mm:ss


protected function makeTimeFromSeconds( $total_seconds )
{
    $horas              = floor ( $total_seconds / 3600 );
    $minutes            = ( ( $total_seconds / 60 ) % 60 );
    $seconds        [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Una sencilla función que dado un número de segundos, nos devuelve el tiempo en formato hh:mm:ss</p>
<pre class="brush: php;">

protected function makeTimeFromSeconds( $total_seconds )
{
    $horas              = floor ( $total_seconds / 3600 );
    $minutes            = ( ( $total_seconds / 60 ) % 60 );
    $seconds            = ( $total_seconds % 60 );

    $time['horas']      = str_pad( $horas, 2, &quot;0&quot;, STR_PAD_LEFT );
    $time['minutes']    = str_pad( $minutes, 2, &quot;0&quot;, STR_PAD_LEFT );
    $time['seconds']    = str_pad( $seconds, 2, &quot;0&quot;, STR_PAD_LEFT );

    $time               = implode( ':', $time );

    return $time;
}
</pre>
<p>Espero os sea de utilidad.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/pasar-segundos-a-horas-minutos-segundos/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>La clase sfConfig de Symfony</title>
		<link>http://www.tecnoretales.com/programacion/la-clase-sfconfig-de-symfony/</link>
		<comments>http://www.tecnoretales.com/programacion/la-clase-sfconfig-de-symfony/#comments</comments>
		<pubDate>Sat, 10 Oct 2009 21:05:27 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Frameworks]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Symfony]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=701</guid>
		<description><![CDATA[Aquí os dejo algo de información sobre como solicitar variables de configuración en symfony además de un listado muy útil con todas las variables que Symfony trae predefinidas.
Cómo pedir variables definidas
Se puede llamar a la función estática get del objeto sfConfig para solicitar cualquier variable definida pasándo dos valores. El primero indica el nombre de [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Aquí os dejo algo de información sobre como solicitar variables de configuración en symfony además de un listado muy útil con todas las variables que Symfony trae predefinidas.</p>
<h3>Cómo pedir variables definidas</h3>
<p>Se puede llamar a la función estática get del objeto sfConfig para solicitar cualquier variable definida pasándo dos valores. El primero indica el nombre de la variable solicitada y el segundo, el valor que retornará en caso de no existir dicha variable.</p>
<pre><strong>sfConfig::get('sf_config_variable', 'The default value'); </strong>// The default is optional</pre>
<p><span id="more-701"></span>Además de las variables que symfony trea configuradas por defecto, podemos añadir nuestras propias variables. Esto se hace en los archivos app.yml. Tenemos un app.yml global para todas las aplicaciones y módulos de nuestro proyecto localizado en:</p>
<pre>/path/to/project/[PROJECT_NAME]/config/app.yml</pre>
<p>y otro para cada una de las aplicaciones:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/config/app.yml</pre>
<p>NOTA! Si existen dos variables con el mismo nombre en el app.yml global y en el de aplicación, este último valor sobreescribirá el valor global.</p>
<p>Para solicitar una variable definida en uno de estos archivos app.yml devemos añadir app_ al nombre de la variable como se muestra en el siguiente ejemplo:</p>
<pre>sfConfig::get('<strong>app_</strong>sf_config_variable');</pre>
<p>Si en el archivo app.yml definimos la variable en cascada, como por ejemplo:</p>
<pre>all:
  admin:
    email: admin@mail.bla
</pre>
<p>Deberemos acceder a ella añadiendo los diferentes niveles en la llamada:</p>
<pre>sfConfig::get('<strong>app_</strong>admin_email');
También podemos acceder a los valores configurados en settings.yml añadiendo el prefijo “sf_” al valor que queremos recuperar.
</pre>
<h3>Variables definidas por Symfony Framework</h3>
<pre><strong>sf_symfony_lib_dir</strong></pre>
<p>Path real a la carpeta lib del framework:</p>
<pre>/usr/share/php/symfony/symfony12/lib</pre>
<h3>Project Structure and Layout</h3>
<pre><strong>sf_root_dir</strong></pre>
<p>Path a la raiz del projecto:</p>
<pre>/path/to/project/[PROJECT_NAME]</pre>
<pre><strong>sf_apps_dir</strong></pre>
<p>Path a la carpeta &#8220;apps&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps</pre>
<pre><strong>sf_lib_dir</strong></pre>
<p>Path a la carpeta &#8220;lib&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/lib</pre>
<pre><strong>sf_log_dir</strong></pre>
<p>Path a la carpeta &#8220;log&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/log</pre>
<pre><strong>sf_data_dir</strong></pre>
<p>Path a la carpeta &#8220;data&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/data</pre>
<pre><strong>sf_config_dir</strong></pre>
<p>Path a la carpeta &#8220;config&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/config</pre>
<pre><strong>sf_test_dir</strong></pre>
<p>Path a la carpeta &#8220;test&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/test/</pre>
<pre><strong>sf_doc_dir</strong></pre>
<p>Path a la carpeta &#8220;doc&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/doc</pre>
<pre><strong>sf_plugins_dir</strong></pre>
<p>Path a la carpeta de &#8220;plugins&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/plugins</pre>
<pre><strong>sf_cache_dir</strong></pre>
<p>Path a la carpeta &#8220;cache&#8221; del proyecto:</p>
<pre>/path/to/project/[PROJECT_NAME]/cache</pre>
<pre><strong>sf_web_dir</strong></pre>
<p>Path a la carpeta pública &#8220;web&#8221;:</p>
<pre>/path/to/project/[PROJECT_NAME]/web</pre>
<pre><strong>sf_upload_dir</strong></pre>
<p>Path a la carpeta pública de &#8220;uploads&#8221;:</p>
<pre>/path/to/project/[PROJECT_NAME]/web/uploads</pre>
<h3>Application Information</h3>
<pre><strong>sf_app</strong></pre>
<p>El nombre de la aplicación en la que está el archivo, como por ejemplo &#8220;frontend&#8221; o &#8220;backend&#8221;.</p>
<pre><strong>sf_environment</strong></pre>
<p>Entorno de desarrollo actual como por ejemplo &#8220;dev&#8221;.</p>
<pre><strong>sf_debug</strong></pre>
<p>Devuelve el estado actual del modo debug. Puede estar activado &#8220;1&#8243; o desactivado &#8220;0&#8243;.</p>
<h3>Application Structure and Layout</h3>
<pre><strong>sf_app_dir</strong></pre>
<p>Path a la carpeta de la aplicación actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]</pre>
<pre><strong>sf_app_config_dir</strong></pre>
<p>Path a la carpeta &#8220;config&#8221; de la aplicación actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/config</pre>
<pre><strong>sf_app_lib_dir</strong></pre>
<p>Path a la carpeta &#8220;lib&#8221; de la aplicación actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/lib</pre>
<pre><strong>sf_app_module_dir</strong></pre>
<p>Path a la carpeta &#8220;modules&#8221; de la aplicación actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/modules</pre>
<pre><strong>sf_app_template_dir</strong></pre>
<p>Path a la carpeta &#8220;templates&#8221; de la aplicación actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/templates</pre>
<pre><strong>sf_app_i18n_dir</strong></pre>
<p>Path a la carpeta &#8220;i18n&#8221; de la aplicación actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/i18n</pre>
<h3>Cache Structure and Layout</h3>
<pre><strong>sf_app_base_cache_dir</strong></pre>
<p>Path a la carpeta de la aplicación actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]</pre>
<pre><strong>sf_app_cache_dir</strong></pre>
<p>Path a la carpeta de la aplicación actual en el entorno de desarrollo actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]/dev</pre>
<pre><strong>sf_template_cache_dir</strong></pre>
<p>Path a la carpeta &#8220;template&#8221; de la aplicación actual en el entorno de desarrollo actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]/dev/template</pre>
<pre><strong>sf_i18n_cache_dir</strong></pre>
<p>Path a la carpeta &#8220;i18n&#8221; de la aplicación actual en el entorno de desarrollo actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]/dev/i18n</pre>
<pre><strong>sf_config_cache_dir</strong></pre>
<p>Path a la carpeta &#8220;config&#8221; de la aplicación actual en el entorno de desarrollo actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]/dev/config</pre>
<pre><strong>sf_test_cache_dir</strong></pre>
<p>Path a la carpeta &#8220;test&#8221; de la aplicación actual en el entorno de desarrollo actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]/dev/test</pre>
<pre><strong>sf_module_cache_dir</strong></pre>
<p>Path a la carpeta &#8220;modules&#8221; de la aplicación actual en el entorno de desarrollo actual dentro de la caché.</p>
<pre>/path/to/project/[PROJECT_NAME]/cache/[APP_NAME]/dev/modules</pre>
<h3>Application Settings</h3>
<pre><strong>sf_error_404_module</strong></pre>
<p style="padding-left: 30px;">Módulo que ha hecho saltar el error 404.</p>
<pre><strong>sf_error_404_action</strong></pre>
<p style="padding-left: 30px;">Acción que ha hecho saltar el error 404.</p>
<pre><strong>sf_logging_enabled</strong></pre>
<p style="padding-left: 30px;">Valor boleano que nos indica si el loggin de la web está activo &#8220;1&#8243; o no &#8220;0&#8243;.</p>
<pre><strong>sf_escaping_strategy</strong></pre>
<p style="padding-left: 30px;">Valor boleano que indica si la clase sfView está usando Escaping Strategy &#8220;1&#8243; o no &#8220;0&#8243;.</p>
<pre><strong>sf_no_script_name</strong></pre>
<p style="padding-left: 30px;">Valor boleano que indica si la aplicación requiere nombre de script.</p>
<pre><strong>sf_csrf_secret</strong></pre>
<p style="padding-left: 30px;">La clave CSRF secreta configurada en la aplicación.</p>
<h3>También:</h3>
<p>Se puede acceder a la información del actual contexto con las siguientes funciones:</p>
<pre><strong>sfContext::getInstance()-&gt;getActionName();</strong></pre>
<p>Devuelve el nombre de la acción actual. También puede llamarse desde los templates con  $this-&gt;getActionName().</p>
<pre><strong>sfContext::getInstance()-&gt;getModuleName();</strong></pre>
<p>Nombre del módulo actual. También puede llamarse desde los templates con $this-&gt;getModuleName().</p>
<pre><strong>sfContext::getInstance()-&gt;getModuleDirectory();</strong></pre>
<p>Path al directorio del módulo actual:</p>
<pre>/path/to/project/[PROJECT_NAME]/apps/[APP_NAME]/modules/[MODULE_NAME]</pre>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/la-clase-sfconfig-de-symfony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; float: left; padding-left: 0px; margin: 3px;"><!-- Ad number: 2 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Cómo optimizar tus aplicaciones Web</title>
		<link>http://www.tecnoretales.com/programacion/como-optimizar-tus-aplicaciones-php/</link>
		<comments>http://www.tecnoretales.com/programacion/como-optimizar-tus-aplicaciones-php/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 16:57:21 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Navegadores]]></category>
		<category><![CDATA[Programación]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPBarcelona]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=685</guid>
		<description><![CDATA[Manuel Aguilar publicó una magnífica presentación sobre cómo optimizar aplicaciones Web dada en la PHP Barcelona Conference 2008 y he considerado interesante recopilar a modo de resumen las ideas más importantes de ese artículo, en cualquier caso, recomiendo la lectura del mismo para recoger toda su esencia y ampliar información.
Partiendo de un estudio de Yahoo! [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><a href="http://www.tecnoretales.com/wp-content/uploads/2009/10/internet-speed.jpg"><img class="alignleft size-full wp-image-693" title="Optimizar aplicaciones PHP" src="http://www.tecnoretales.com/wp-content/uploads/2009/10/internet-speed.jpg" alt="Optimizar aplicaciones PHP" width="200" height="200" /></a>Manuel Aguilar publicó una magnífica presentación sobre cómo <strong>optimizar aplicaciones Web</strong> dada en la PHP Barcelona Conference 2008 y he considerado interesante recopilar a modo de resumen las ideas más importantes de ese artículo, en cualquier caso, recomiendo la lectura del mismo para recoger toda su esencia y ampliar información.</p>
<p>Partiendo de un estudio de Yahoo! que dice que el 80% del tiempo de carga de una web corresponde al lado del cliente, podemos seguir una serie de reglas que aumentarán significativamente la percepción de velocidad del usuario.<span id="more-685"></span></p>
<p><strong>1. Aumentar el tiempo de expiración</strong> de los elementos cacheados que no varían como CSS o JavaScript: Para forzar la carga de los mismos cuando haya cambios, podemos añadir el md5 del contenido del fichero como parámetro, así el navegador lo recargará cuando cambie el hash. Ej: style.css?hash=f9d35dcf65d8f67e288ae2f12fc069f7</p>
<p><strong>2. No colocar código JavaScript o estilos inline</strong>: es mejor colocarlos como ficheros externos fácilmente cacheables, de este modo evitaremos descargar todo el html por un cambio de estilo.</p>
<p><strong>3. Reducir el número de ficheros externos</strong>: Los navegadores sólo pueden aceptar dos descargas simultaneas de un mismo dominio, si unimos nuestras librerías JavaScript y nuestros CSS en un único archivo evitaremos dilatar innecesariamente el tiempo de descarga.</p>
<p><a href="http://www.tecnoretales.com/wp-content/uploads/2009/10/firebug.jpg"><img class="aligncenter size-full wp-image-686" title="Firebug Net" src="http://www.tecnoretales.com/wp-content/uploads/2009/10/firebug.jpg" alt="Firebug Net" width="582" height="149" /></a></p>
<p><strong>4. Usar subdominios</strong> diferentes para las imágenes y para los elementos estáticos: Conseguiremos así descargar 8 elementos de manera simultánea y reducir la carga de la web. Si además podemos optimizar un apache aparte para servir las imágenes, conseguiremos un mejor rendimiento al servirlas.</p>
<p><strong>5. Compactar los ficheros JavaScript</strong>: Existen programas gratuitos como <a title="Yui Compressor" href="http://yuilibrary.com/downloads/#yuicompressor" target="_blank">YUI Compressor</a> que comprimen los archivos JavaScript consiguiendo resultados de hasta el 50%.</p>
<p><strong>6. Utilizar compresión en el servidor</strong>: Los servidores modernos como Apache son capaces de comprimir la información antes de servirla, posteriormente los navegadores actuales como Explorer o Firefox la descomprimen de manera transparente al usuario.</p>
<p><strong>7. Fomentar el uso de imágenes con muchos sprites</strong>: Estas son imágenes grandes que contienen muchas imágenes pequeñas. Según lo comentado en el punto 3 tardaremos mucho menos en descargar una imágen con 50 sprites que 50 sprites de manera individual. Posteriormente utilizaremos CSS para definir la sección de imágen que se mostrará.</p>
<p><a href="http://www.tecnoretales.com/wp-content/uploads/2009/10/sprites.jpg"><img class="aligncenter size-full wp-image-687" title="Sprites" src="http://www.tecnoretales.com/wp-content/uploads/2009/10/sprites.jpg" alt="Sprites" width="336" height="153" /></a></p>
<p><strong>8. Mover los CSS al &lt;head&gt;</strong>: Navegadores como Explorer no renderizan la web hasta que no tienen todos los CSS, si los colocas en la cabecera podrá empezar antes a mostrar la web.</p>
<p><strong>9. Mover los JavaScript al final de la página</strong>: Hasta que un fichero JavaScript no se ha leido completamente el navegador no continua con la carga. Si los movemos al final de la página este se estará cargando cuando el usuario ya está navegando por la web.</p>
<p><strong>10. Evitar llamadas duplicadas a JavaScript y CSS</strong>: Si el navegador encuentra un fichero JavaScript para la carga hasta que este se ha leido completamente, si posteriormente vuelve a encontrar una llamada al mismo JS, volverá a parar la carga hasta que se haya leido.</p>
<p style="text-align: right;">Vía | <a title="Optimización aplicaciones PHP" href="http://www.slideshare.net/maguilar/phpbarcelona-conference-optimizacin-aplicaciones-php-client-side" target="_blank">Optimización aplicaciones PHP</a></p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/como-optimizar-tus-aplicaciones-php/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Implementando un sistema de caché en PHP</title>
		<link>http://www.tecnoretales.com/programacion/implementando-un-sistema-de-cache-en-php/</link>
		<comments>http://www.tecnoretales.com/programacion/implementando-un-sistema-de-cache-en-php/#comments</comments>
		<pubDate>Mon, 21 Sep 2009 09:40:24 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Caché]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=658</guid>
		<description><![CDATA[Hace unos días, os comentaba que es una caché y como entenderla en el marco de la programación web. Para seguir con el aprendizaje de este sistema, he desarrollado una pequeña clase que permite cachear información (strings, arrays, resultados de base de datos, objetos&#8230;) en nuestra máquina y descongestionar así el motor de base de [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Hace unos días, os comentaba <a title="Qué es una caché?" href="http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/" target="_blank">que es una caché</a> y como entenderla en el marco de la programación web. Para seguir con el aprendizaje de este sistema, he desarrollado una pequeña <strong>clase que permite cachear información</strong> (strings, arrays, resultados de base de datos, objetos&#8230;) en nuestra máquina y descongestionar así el motor de base de datos, por poner un ejemplo.</p>
<p>Lo primero que debemos hacer es <strong>pensar en que necesitamos</strong> para su correcto funcionamiento, así que, manos a la obra.</p>
<p>Como sabemos, una caché es un sistema al que le pasamos un objeto X y él lo almacenará en su sistema de una manera determinada, por lo tanto, necesitaremos una función que dado un identificador único y unos datos, guardará la información. Además de esto, necesitamos indicarle un <strong>tiempo de vida</strong> (ttl) a esa información cacheada, sino estaremos devolviendo eternamente el valor almacenado.<span id="more-658"></span></p>
<p>Un concepto que nos puede resultar interesante es el de <strong>caché de grupo</strong>. Imaginemos que tenemos un sistema que va cacheando información de nuestra base de datos; tenemos una tabla user y una tabla user_profile y cacheamos los resultados de ambas tablas por separado. Imaginemos también que por temas de LOPD el usuario solicita que eliminemos todos sus datos de nuestras máquinas, así que eliminaremos el registro de la tabla user y user_profile y procederemos a eliminar el cacheo de los datos de cada tabla por separado. Si tuviesemos agrupada la información de usuario, con una única llamada a la función remove y pasándole el identificador de grupo, eliminará la caché de ambas tablas.</p>
<p>A medida que vaya explicando cada función, os pondré el resultado final para que os hagais una idea de como va quedando el código:</p>
<pre class="brush: php;">
    public function save ( $id, $group_id = 'default', $data, $ttl = self::CACHE_TTL )
    {
        if ( $this-&gt;caching )
        {
            $this-&gt;set_file_routes( $id, $group_id );

            // If the directory don't exists, I create.
            if ( !is_dir ( $this-&gt;file_path ) )
            {
                if ( !mkdir ( $this-&gt;file_path, 0777, true ) )
                {
                    return false;
                }
            }

            if ( !is_array ( $data ) &amp;amp;&amp;amp; !is_object( $data ) )
            {
                $data = array ( $data );
            }

            // Serialize data for caching.
            $data = serialize ( $data );

            // I get a hash to check integrity in the future.
            $hash = md5 ( $data );

            $meta['expiration_time']    = time () + $ttl;
            $meta['integrity']          = $hash;
            $meta['data']               = $data;

            // Serialize meta info to put in a file.
            $data    = serialize ( $meta );

            return file_put_contents ( $this-&gt;file, $data, LOCK_EX );
        }

        return false;
    }</pre>
<p>A su vez, debemos poder recuperar los objetos almacenados en un futuro, así que también programaremos una función que dado un identificador y un identificador de grupo, devolverá unos datos <strong>get($id, $group_id)</strong>. El tener que pasar el identificador de grupo en esta función es debido a que las rutas de almacenamiento se generan a partir de ambos identificadores.</p>
<pre class="brush: php;">
    public function get ( $id, $group_id = 'default' )
    {
        if ( $this-&gt;caching )
        {
            $this-&gt;set_file_routes ( $id, $group_id );

            if ( !file_exists ( $this-&gt;file ) )
            {
                return false;
            }

            $meta    = file_get_contents ( $this-&gt;file_path . $this-&gt;file_name );
            $meta    = unserialize ( $meta );

            $check_expiration   = $this-&gt;check_expiration ( $meta['expiration_time'] );
            $check_integrity    = $this-&gt;check_integrity ( $meta['integrity'], $meta['data'] );

            // Expiration and integrity control.
            if ( $check_expiration &amp;amp;&amp;amp; $check_integrity )
            {
                $data = unserialize ( $meta['data'] );

                return $data;
            }
            else
            // Clean the expired or not correct caché.
            {
                $this-&gt;remove ( $id, $group_id );

                return false;
            }
        }

        return false;
    }
</pre>
<p>Como último elemento fundamental, necesitaremos poder borrar unos datos de la caché en caso de que ya no sean válidos porque se han modificado o borrado, así que crearemos una función que dado un identificador y un identificador de grupo, elimine el objeto cacheado. A esta función la llamaremos <strong>remove($id, $group_id)</strong>.</p>
<pre class="brush: php;">
    public function remove( $id, $group_id = 'default', $group_level = false )
    {
        $this-&gt;set_file_routes( $id, $group_id );

        // Don't remove the 'default' group
        if ( $group_level &amp;amp;&amp;amp; $group_id != 'default' )
        {
            if ( !$this-&gt;group_path || empty ( $this-&gt;group_path ) )
            {
                return false;
            }

            return $this-&gt;del_tree ( $this-&gt;group_path );
        }
        // Check that the file exists and delete the file cached folder
        elseif ( $this-&gt;file_path &amp;amp;&amp;amp; !empty ( $this-&gt;file_path ) )
        {
            return $this-&gt;del_tree ( $this-&gt;file_path );
        }
        else
        {
            return false;
        }
    }
</pre>
<p>Como sabemos, la caché guarda los objetos durante un tiempo determinado y una vez ha pasado ese tiempo, el objeto se considera inservible, por lo tanto añadiremos una función <strong>check_expiration()</strong> que nos dirá si el objeto está caducado.</p>
<pre class="brush: php;">
private function check_expiration ( $expiration_time )
{
return ( time() &lt; $expiration_time );
}
</pre>
<p>¿Qué pasa si cuando estoy almacenando los datos hay un problema de escritura y los datos se almacenan mal? Podría suceder que los <strong>datos almacenados esten corruptos</strong>, y todas las devoluciones de dicho objeto fueran defectuosas. Para comprobar que los datos guardados no están corruptos, crearemos una función <strong>check_integrity()</strong>.</p>
<pre class="brush: php;">
    private function check_integrity ( $read_hash, $serialized_data )
    {
        $hash = md5 ( $serialized_data );

        return ( $read_hash == $hash );
    }
</pre>
<p>Además de estas funciones, crearemos varias constantes que definirán los valores de configuración del sistema como pueden ser el tiempo de vida (ttl) de un objeto cacheado por defecto o el directorio en el que se guardará la caché.</p>
<pre class="brush: php;">
    // Path to cache dir.
    const CACHE_DIR = 'cache/';

    // Max. time to life of this cache.
    const CACHE_TTL = '3600';

    // Extension to use in cache files.
    const CACHE_EXT = '.cache';
</pre>
<p>En el código se llama a las funciones <strong>get_status()</strong> y <strong>set_status()</strong> que sirven comprobar si está activo el sistema de cacheo y habilitar/deshabilitar respectivamente. <strong>set_file_routes()</strong> crea las rutas en las que se almacenará los datos cacheados y <strong>get_key()</strong> crea hashes a partir de un identificador. Por último, <strong>del_tree()</strong> nos ayudará a eliminar un directorio de manera recursiva.</p>
<pre class="brush: php;">
    public function get_status ()
    {
        return $this-&gt;caching;
    }

    public function set_status ( $status )
    {
        $this-&gt;caching = $status;
    }

    private function set_file_routes ( $id, $group_id )
    {
        $key_name    = $this-&gt;get_key ( $id );
        $key_group   = $this-&gt;get_key ( $group_id );

        $level_one = $key_group;
        $level_two = substr ( $key_name, 0, 4 );

        $this-&gt;group_path   = self::CACHE_DIR . $level_one . '/';
        $this-&gt;file_path    = self::CACHE_DIR . $level_one . '/' . $level_two . '/';
        $this-&gt;file_name    = $key_name . self::CACHE_EXT;
        $this-&gt;file         = $this-&gt;file_path . $this-&gt;file_name;
    }

    private function get_key ( $id )
    {
        return md5 ( $id );
    }

    private function del_tree ($dir)
    {
        if ( empty ( $dir ) )
        {
            return false;
        }

        if ( !file_exists ( $dir ) )
        {
            return true;
        }

        if ( !is_dir ( $dir ) || is_link ( $dir ) )
        {
            return unlink ( $dir );
        }

        foreach ( scandir ( $dir ) as $item )
        {
            if ( $item == '.' || $item == '..' )
            {
                continue;
            }

            if( is_dir ( $dir . $item ) )
            {
                $this-&gt;del_tree ( $dir . $item . '/' );
            }
            else
            {
                unlink ( $dir . $item );
            }
        }

        return rmdir ( $dir );
    }
</pre>
<p>Puedes descargarte el archivo final desde aquí <a href="http://www.tecnoretales.com/wp-content/uploads/2009/09/cache.class.php.txt" target="_blank">cache.class.php</a>.</p>
<p>Aunque esta caché es perfectamente funcional, este ejercicio nos sirve para <strong>entender un poco más el funcionamiento de un sistema de caché</strong>. Si queremos implementar uno en nuestra aplicación, os recomiendo mirar <a title="CacheLite" href="http://pear.php.net/package/Cache_Lite" target="_blank">CacheLite</a> (si nuestra aplicación es pequeña), <a title="APC" href="http://es2.php.net/apc" target="_blank">APC</a> o <a title="Memcached" href="http://www.danga.com/memcached/" target="_blank">Memcached</a> (si nuestra aplicación es grande y/o con servidores balanceados).</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/implementando-un-sistema-de-cache-en-php/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Qué es una Caché y como aplicarla a la programación Web</title>
		<link>http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/</link>
		<comments>http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/#comments</comments>
		<pubDate>Mon, 14 Sep 2009 08:15:27 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Caché]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Optimización]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=642</guid>
		<description><![CDATA[Vamos a ver que es una caché con un ejemplo muy ilustrativo que leí hace algún tiempo. Supongamos que estamos trabajando en una centralita que facilita números de teléfono de un pueblo relativamente pequeño; para ello, tenemos un listín telefónico común con todos los teléfonos del pais.
Cada vez que recibimos una llamada, cogemos el listín, [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Vamos a ver <strong>que es una caché</strong> con un ejemplo muy ilustrativo que leí hace algún tiempo. Supongamos que estamos trabajando en una centralita que facilita números de teléfono de un pueblo relativamente pequeño; para ello, tenemos un listín telefónico común con todos los teléfonos del pais.</p>
<p>Cada vez que recibimos una llamada, cogemos el listín, realizamos la búsqueda y facilitamos el número encontrado al usuario. Al poco tiempo, nos damos cuenta que la gente suele pedir los teléfonos de los mismos restaurantes y comercios una y otra vez, así que cogemos una libreta pequeña y vamos anotando los números de teléfono que nos solicitan ordenados alfabéticamente para poder <strong>acceder a ellos de manera más rápida</strong> la próxima vez&#8230; felicidades, acabas de crear una caché!<span id="more-642"></span></p>
<p>Sin embargo, el uso de una <strong>caché tiene un pequeño handicap</strong>; imaginemos que nos llama un usuario y nos solicita el teléfono de un comercio. Cogeremos nuestra libreta, lo buscaremos y si no lo encontramos recurriremos al listín, realizaremos la búsqueda en él y facilitaremos el número al usuario. En este momento estamos aumentando ligeramente el tiempo de búsqueda de un número, por ese motivo, la información debe almacenarse en la caché de manera eficiente, y a partir de aquí hay mil teorías sobre como y cuando almacenar la información en una caché.</p>
<p>En resumen y dicho de una manera más técnica un sistema de caché es una zona de memoria en la que se almacenan copias de un objeto original pero al que es mucho más rápido acceder.</p>
<h3><span style="text-decoration: underline;">La Caché en la programación</span>:</h3>
<p>A la hora de construir una aplicación medianamente grande, se hace imprescindible el cachear cierta información para conseguir un rendimiento óptimo. Un sistema de caché correctamente implementado puede <strong>reducir el número de servidores y evitar la sobrecarga</strong> de las máquinas.</p>
<p>Se pueden utilizar diferentes tipos de caché en función del tipo de datos que queramos guardar. Centrándome en la programación web, podemos encontrar:</p>
<ul>
<li><span style="text-decoration: underline;">Caché SQL</span>: Para almacenar en memoria el resultado de ciertas consultas recurrentes y poder así descargar la base de datos. MySQL 5.0 Server tiene soporte nativo para este tipo de caché pero se debe activar expresamente.</li>
<li><span style="text-decoration: underline;">Cachéo de Objetos</span>: En este tipo de caché podemos almacenar objetos, arrays, textos, resultados de funciones, resultados de base de datos&#8230; Podremos almacenar cualquier tipo de información soportada por el sistema de cacheo e indicarle el tiempo de expiración. Ejemplos de este sistema de caché para PHP son APC (Alternative PHP Cache) o Memcached.</li>
<li><span style="text-decoration: underline;">Cacheo de templates</span>: Puede ser de gran utilidad el cachear los resultados HTML al invocar diferentes URL, por ejemplo, el sistema de templates Smarty integra un sistema de caché que permite devolver el HTML de manera eficiente.</li>
</ul>
<h3><span style="text-decoration: underline;">Por qué no debo usar SQLCaché y APC o Memcached?</span></h3>
<p>La caché implementada por MySQL tiene una política en la gestión de su caché muy estricta. Cada vez que hay una escritura en una tabla, elimina toda la caché asociada a dicha tabla y a partir de ese momento, se debe volver a regenerar, por tanto, la entrada de un registro en la tabla implica insertar el registro, regenerar los indices, cachear los datos y por último devolverlos (aumentamos el tiempo de la consulta). Dada esta premisa, podemos extraer la conclusión de que es interesante <strong>activar SQLCaché en una base de datos con muchas lecturas y pocas escrituras</strong>.</p>
<p>A su vez, implementando un sistema de cacheo como APC o Memcached para almacenar la información devuelta por la base de datos dada una consulta, reduce considerablemente el número de lecturas a base de datos.</p>
<p>Por ese motivo, el tener activados estos dos tipos de caché simultaneamente, no solo no mejora el rendimiento de nuestra aplicación sino que lo empeora.</p>
<h3><span style="text-decoration: underline;">Es contraproducente usar APC y Memcached de manera simultanea?</span></h3>
<p>APC proporciona dos tipos de cacheo. Por un lado, evita el continuo compilado de un script PHP, pues a pesar de ser un lenguaje interpretado, PHP pasa todo script a un lenguaje entendible por la máquina antes de ejecutarlo ¿por qué recompilar cada vez el script si no ha cambiado desde la última ejecución? A partir de la versión 6 de PHP parece ser que APC estará activado de forma nativa. Por otra parte, podemos almacenar objetos con el uso de las funciones <a title="APC_add" href="http://es.php.net/manual/en/function.apc-add.php" target="_blank">apc_add</a> y <a title="APC_store" href="http://es.php.net/manual/en/function.apc-store.php" target="_blank">apc_store</a>.</p>
<p>Memcached proporciona un servicio web desacoplado y altamente escalable. <strong>El 95% del top ten y el 80% del top 50 de Alexa utiliza Memcached</strong> precisamente por la facilidad de implementación y de añadir nuevas máquinas para cachear información. APC tiene un rendimiento ligeramente superior, pero si tenemos un sistema con servidores balanceados no podemos compartir la caché entre todas las máquinas porque está vinculada al host, por ese motivo la balanza se ha ido decantando hacia el uso de Memcached.</p>
<p>Si bien, puede ser interesante <strong>utilizar una combinación de ambas</strong>, APC para el <strong>precompilado</strong> de nuestro código y <strong>Memcached para almacenar</strong> la información de base de datos y descargar así nuestro motor de bd.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/que-es-una-cache-y-como-aplicarla-a-la-programacion-web/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>PHP Barcelona Conference 2009</title>
		<link>http://www.tecnoretales.com/programacion/php-barcelona-conference-2009/</link>
		<comments>http://www.tecnoretales.com/programacion/php-barcelona-conference-2009/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 22:03:44 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPBarcelona]]></category>
		<category><![CDATA[PHPUnit]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=635</guid>
		<description><![CDATA[Después del éxito obtenido la pasada edición, el grupo PHPBarcelona ha vuelto a organizar una conferencia para este año. El lugar de encuentro será el CitiLab de Cornellà los días 30 y 31 de Octubre.
Ya se ha abierto la venta anticipada de entradas a un precio increiblemente bajo: 25€ un día y 40€ los dos. [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-636" title="phpbarcelonaconference2009" src="http://www.tecnoretales.com/wp-content/uploads/2009/09/phpbarcelonaconference2009.png" alt="phpbarcelonaconference2009" width="342" height="272" />Después del éxito obtenido la pasada edición, el grupo <a title="PHPBarcelona" href="http://phpbarcelona.org/" target="_blank">PHPBarcelona</a> ha vuelto a organizar una conferencia para este año. El lugar de encuentro será el <a title="CitiLab de Cornellà" href="http://citilab.eu/inici" target="_blank">CitiLab</a> de Cornellà los días 30 y 31 de Octubre.</p>
<p>Ya se ha abierto la venta anticipada de entradas a un precio increiblemente bajo: 25€ un día y 40€ los dos. Puedes adquirir las entradas desde la <a title="PHPBarcelona" href="http://phpbarcelona.org/venta-anticipada-de-entradas-para-la-conference-del-2009" target="_blank">web oficial</a>.</p>
<p>Según anuncian: &#8220;Este año el evento viene cargado de muchas e interesantes novedades: dos días de duración (Viernes y Sábado), <strong>distintas actividades</strong> entremezcladas (ponencias teóricas, talleres prácticos, concursos de programación, etc.), dos líneas de idioma (español e inglés), nuevos y potentes patrocinadores, más <strong>celebridades invitadas</strong>, divertidos regalos y mucho más!&#8221;</p>
<p>Realmente este año los chicos de PHPBarcelona se han puesto las pilas, pues en el cartel de charlas aparecen nombres tan importantes como <strong>Rasmus Lerdorf</strong> (Uno de los creadores de PHP), <strong>Fabien Potencier</strong> (Lead Developer de Symfony), <strong>Derick Rethans</strong> (XDebug) y <strong>Sebastian Bergmann</strong> (Creador de PHPUnit).</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/php-barcelona-conference-2009/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	<!-- google ad injected by adsense-optimizer http://www.adsenseoptimizer.de -->
			<div  style="padding:7px; display: block; margin-left: auto; margin-right: auto; text-align: center;"><!-- Ad number: 3 --><script type="text/javascript"><!--
    	 
    	google_ad_client = "pub-7180773421652966"; google_alternate_color = "FFFFFF";
		google_ad_width = 468; google_ad_height = 60;
		google_ad_format = "468x60_as"; google_ad_type = "text";
		google_ad_channel =""; google_color_border = "FE8B00";
		google_color_link = "FE8B00"; google_color_bg = "FFFFFF";
		google_color_text = "000000"; google_color_url = "D9D9D9";
		google_ui_features = "rc:6"; //--></script>
		<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script></div>	<item>
		<title>Diseñando una aplicación</title>
		<link>http://www.tecnoretales.com/programacion/disenando-una-aplicacion/</link>
		<comments>http://www.tecnoretales.com/programacion/disenando-una-aplicacion/#comments</comments>
		<pubDate>Thu, 10 Sep 2009 17:49:32 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[Humor]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=626</guid>
		<description><![CDATA[Veo en el blog Distro-Geek una viñeta que define a la perfección el modus operandi de muchas empresas a la hora de diseñar una aplicación&#8230; lamentablemente, esto pasa más frecuentemente de lo recetado por el médico.

]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p>Veo en el blog Distro-Geek una viñeta que define a la perfección el modus operandi de muchas empresas a la hora de diseñar una aplicación&#8230; lamentablemente, esto pasa más frecuentemente de lo recetado por el médico.</p>
<p style="text-align: center;"><img class="aligncenter size-full wp-image-627" title="Diseñando una aplicación" src="http://www.tecnoretales.com/wp-content/uploads/2009/09/diseno_aplicacion.jpg" alt="Diseñando una aplicación" width="603" height="438" /></p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/disenando-una-aplicacion/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Code Golf &#8211; Pasatiempo para programadores</title>
		<link>http://www.tecnoretales.com/programacion/code-golf-pasatiempo-para-programadores/</link>
		<comments>http://www.tecnoretales.com/programacion/code-golf-pasatiempo-para-programadores/#comments</comments>
		<pubDate>Thu, 27 Aug 2009 12:03:13 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=602</guid>
		<description><![CDATA[Code golf es un adictivo pasatiempos para programadores en el que el objetivo es conseguir una solución a un sencillo problema con el menor número de teclas picadas al programarlo (o lo que es lo mismo el archivo con menor peso en bytes es el que gana).
En la web se plantean diferentes retos y a [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><a title="Code Golf" href="http://http://codegolf.com/" target="_blank"><img class="alignleft size-full wp-image-603" title="Code Golf" src="http://www.tecnoretales.com/wp-content/uploads/2009/08/logo.png" alt="Code Golf" width="239" height="54" />Code golf</a> es un adictivo pasatiempos para programadores en el que el objetivo es conseguir una solución a un sencillo problema con el menor número de teclas picadas al programarlo (o lo que es lo mismo el archivo con menor peso en bytes es el que gana).</p>
<p>En la web se plantean diferentes retos y a partir de ahí se van marcando los mejores resultados a medida que los usuarios van subiendo sus scripts. Puedes subir tu mini-programa en uno de los siguientes lenguajes: PERL, PHP, Phyton o Ruby.<span id="more-602"></span></p>
<p>Si teneis dudas sobre probar este pasatiempos, os doy un ejemplo del tipo de programas que suelen pedir:</p>
<p><strong><a title="Home On The Range" href="http://codegolf.com/home-on-the-range" target="_blank">Home On The Range</a></strong></p>
<p>Diseñar un programa simple que dada una ristra de números, sustituya las secuencias numéricas seguidas por el primer y último número de la secuencia separadas por un guión. Dicho así suena complicado, pero es sencillo si vemos un ejemplo de la salida por pantalla:</p>
<ul>
<li>&#8220;1 2 3&#8243; =&gt; &#8220;1-3.&#8221;</li>
<li>&#8220;1 2 3 5 7 8&#8243; =&gt; &#8220;1-3, 5, 7-8.&#8221;</li>
<li>&#8220;1 3 4 5 7&#8243; =&gt; &#8220;1, 3-5, 7.&#8221;</li>
</ul>
<p>Además de un entretenido juego, Code Golf nos sirve de entrenamiento para optimizar nuestro código a la hora de trabajar en nuestros desarrollos profesionales.</p>
<p>Probádlo y juzgad.</p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/code-golf-pasatiempo-para-programadores/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Novedades de PHP6</title>
		<link>http://www.tecnoretales.com/programacion/novedades-de-php6/</link>
		<comments>http://www.tecnoretales.com/programacion/novedades-de-php6/#comments</comments>
		<pubDate>Tue, 04 Aug 2009 08:35:36 +0000</pubDate>
		<dc:creator>Manel Pérez Mata</dc:creator>
				<category><![CDATA[Programación]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Unicode]]></category>

		<guid isPermaLink="false">http://www.tecnoretales.com/?p=589</guid>
		<description><![CDATA[Los desarrolladores del motor de PHP llevan ya varios meses trabajando en la versión 6. De momento no parece que vaya a ver la luz en breve, pues acaban de liberar la versión 5.3 para postergar en la medida de lo posible la aparición de la nueva versión. En cualquier caso, es interesante estar al [...]]]></description>
			<content:encoded><![CDATA[<!-- google_ad_section_start --><p><img class="alignleft size-full wp-image-598" title="php6" src="http://www.tecnoretales.com/wp-content/uploads/2009/08/php6.jpg" alt="php6" width="230" height="230" />Los desarrolladores del motor de PHP llevan ya varios meses trabajando en la versión 6. De momento no parece que vaya a ver la luz en breve, pues acaban de liberar la versión 5.3 para postergar en la medida de lo posible la aparición de la nueva versión. En cualquier caso, es interesante estar al día e ir preparando nuestros desarrollos actuales para las posibles incompatibilidades con la nueva versión.</p>
<p>Recientemente preguntaban a Zeev Suraski, co-fundador de Zend Technologies Inc. sobre la versión 6 de PHP de la que se lleva algún tiempo hablando pero que parece que no acaba de ver la luz. En la entrevista, Zeev nos comentaba:</p>
<blockquote><p><strong>PHP6 es un proyecto mucho más difícil que PHP4 y 5</strong> principalmente por dos razones:</p>
<ul>
<li>La cantidad de código PHP que hay afuera, es tan inmensa.</li>
<li>Cada pequeña incompatibilidad que uno introduce se convierte en un horrible dolor de cabeza para mucha gente. Y combinado con la principal cosa que queremos hacer con PHP6, que es la introducción de soporte nativo para Unicode,<strong> es imposible no introducir una cantidad significativa de incompatibilidades en el lenguaje</strong>. No sé cómo va a resultar esto, estoy siendo completamente honesto.</li>
</ul>
</blockquote>
<p><span id="more-589"></span>Según su prespuesta, parecía lógico preguntarle sobre como de complicada se prevé que sea la migración de una plataforma PHP5 actual a la nueva versión:</p>
<blockquote><p>La migración de la versión 4 a la versión 5 fue bastante exitosa. Tomó algunos años, pero hoy PHP5 ya es mucho más popular de lo que la versión 4 jamás lo fue. Hemos tomado la decisión de no apurar la transición, así que actualmente nos hemos concentrando en PHP 5.3.</p>
<p>En esta versión que ya ha visto la luz, hemos agregado algunas de las características que originalmente estaban planeadas para PHP6, como por ejemplo, los espacios de nombres (namespaces). Probablemente pase <strong>bastante tiempo antes de que PHP6 seará liberado</strong>.</p></blockquote>
<h3>¿Qué novedades introduce PHP6?</h3>
<p>El 11 de Noviembre del 2005 el núcleo central de desarrolladores de PHP se encontraron en París para decidir el camino que iva a tomar PHP6. Los principales cambios que se plantearon implementar son:</p>
<ul>
<li><strong>Unicode:</strong> Es el cambio más relevante en esta nueva versión. En PHP5 se puede activar Unicode bajo petición, pero en este caso, se dispara el consumo de recursos debido a que PHP tiene que almacenar todas las variantes de funciones, métodos y clases tanto en Unicode como en no-Unicode en la tabla de símbolos.</li>
<li><strong>Register Globals eliminadas:</strong> Cualquier variable global registrada que aparezca en el código nos devolverá un error E_CORE_ERROR y un enlace a la documentación en la que se detalla porqué es contraproducente utilizarlo. Para la versión actual 5.3 ya han sido marcadas como deprecated.</li>
<li><strong>Magic Quotes eliminadas:</strong> El bajo rendimiento de <em>magic_quotes</em>, <em>magic_quotes_sybase</em> y <em>magic_quotes_gpc</em> ha provocado la decisión de colocarlas como deprecated en la versión actual 5.3 y de eliminarlas definitivamente para la versión 6.</li>
<li><strong>Modo seguro eliminado:</strong> La razón es que aparentemente daba una idea errónea de que hacía a PHP seguro, cuando en realidad no mejoraba en nada la seguridad, si bien, open_basedir se conservará.</li>
<li><strong>‘var’ y ‘public’ tendrán el mismo significado:</strong> Con PHP6 una variable &#8216;var&#8217; va a considerarse &#8216;public&#8217; adquiriendo idéntico significado. Desaparecerá el warning mostrado al usarlo aunque tengamos configurado  el nivel de error como E_STRICT.</li>
<li><strong>Return by Reference devolverá un error:</strong> Tanto  $foo =&amp; new StdClass() como function &amp;foo producirán ahora un error  E_STRICT.</li>
<li><strong>Compatibilidad zend.ze1 eliminada:</strong> ze1 intentó conservar el viejo comportamiento de PHP4, pero aparentemente “ni siquiera funciona al 100%”, así que será eliminado por completo y dará un error E_CORE_ERROR si se detecta.</li>
<li><span id="section"><strong>Se abandona el soporte de Freetype1 y GD1:</strong> Bibliotecas totalmente obsoletas y que no tiene sentido seguir manteniendo.</span></li>
<li><span id="section"><strong>FastCGI siemper activado:</strong> El código de </span>FastCGI será renovado y estará siempre disponible para la CGI SAPI,  no podrá ser desactivado.</li>
<li><strong>Register Long Arrays eliminado:</strong> En PHP6 sólo $_POST y $_GET serán aceptados, HTTP_*_VARS va a devolver un error.</li>
<li><strong>Las extensiones XMLReader y XMLWriter movidas:</strong> Se moverán al núcleo de distribución y permanecerán activas por defecto.</li>
<li><strong>Extensión ereg eliminada:</strong> La introducción de las librerías ICU (necesarias para el tema de Unicode) han motivado el movimiento de la extensión ereg a PECL y por lo tanto será eliminada de PHP. A partir de ese momento se deberán usar la nueva extensión de expresiones basadas en ICU.</li>
<li><strong>Fileinfo por defecto:</strong> La extensión Fileinfo se verá desplazada al núcleo de la distribución y estará activada por defecto.</li>
</ul>
<p>Si bien, a pesar de que parece que la línea seguída por los desarrolladores es esta que se comenta en el artículo, no se podría asegurar al 100% que la versión 6 definitiva incorpore todos los cambios mencionados o no aparezca algun otro importante no descrito.</p>
<p style="text-align: right;">Vía | <a href="http://www.maestrosdelweb.com/editorial/php6/" target="_blank">Maestrosdelweb.com</a></p>
<!-- google_ad_section_end -->]]></content:encoded>
			<wfw:commentRss>http://www.tecnoretales.com/programacion/novedades-de-php6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

