<?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>PHPBSD.net &#187; cache</title>
	<atom:link href="http://www.phpbsd.net/tag/cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phpbsd.net</link>
	<description>Blogueando sobre PHP, BSD, SEO, AJAX, Seguridad, Rendimiento... y mucho más</description>
	<lastBuildDate>Thu, 07 Oct 2010 11:57:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Cache de páginas estáticas para PHP</title>
		<link>http://www.phpbsd.net/2007/05/16/cache-de-paginas-estaticas-para-php/</link>
		<comments>http://www.phpbsd.net/2007/05/16/cache-de-paginas-estaticas-para-php/#comments</comments>
		<pubDate>Wed, 16 May 2007 01:31:45 +0000</pubDate>
		<dc:creator>Oriol</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[output-buffer]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[webmaster]]></category>

		<guid isPermaLink="false">http://www.phpbsd.net/2007/05/16/cache-de-paginas-estaticas-para-php/</guid>
		<description><![CDATA[El motor de PHP es uno de los más rápidos generando páginas web aún así nunca será tan rápido como no tener que generar nada y que el servidor web devuelva páginas estáticas. A pesar de disponer de una aplicación web escrita en PHP podemos conseguir la misma velocidad que en una web estática cacheando [...]


Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li><li><a href='http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/' rel='bookmark' title='Permanent Link: Instalación del APC (Alternative PHP Cache) sobre FreeBSD'>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</a></li><li><a href='http://www.phpbsd.net/2007/07/12/nuevos-estandares-para-las-pear2/' rel='bookmark' title='Permanent Link: Nuevos estándares para las PEAR2'>Nuevos estándares para las PEAR2</a></li></ul>]]></description>
			<content:encoded><![CDATA[<p>El motor de PHP es uno de los más rápidos generando páginas web aún así nunca será tan rápido como no tener que generar nada y que el servidor web devuelva <strong>páginas estáticas</strong>. A pesar de disponer de una aplicación web escrita en PHP podemos conseguir la misma <strong>velocidad</strong> que en una web estática cacheando las páginas generadas. Lo que se porpone a continuación es un <strong>sistema de cache</strong> donde las páginas sólo se generarán la primera vez que se acceda a ellas, en siguientes peticiones el servidor web devolverá las páginas estáticas generadas.</p>
<p>Existen varias propuestas de sistemas de cache donde siempre se ejecuta un script PHP trabajando con el output-buffer para guardar la respuesta. Estos sistemas de cache tiene el inconveniente de que a pesar de tener la página cacheada siempre estamos ejecutando un script PHP con el coste en rendimiento que ello conlleva. Como solución se propone trabajar con el output-buffer pero usar la directiva de configuración <a target="_blank" href="http://httpd.apache.org/docs/2.0/mod/core.html#errordocument" title="errordocument - core - Servidor HTTP Apache">ErrorDocument</a> del Apache para que si ya tenemos la página generada no se ejecute ni un script PHP.</p>
<p>La directiva <em>ErrorDocument</em> se usa para configurar lo que el servidor devolverá al cliente en caso de error. Pues bien, se trata de configurar el error que indica que no existe la página solicitada (error 404) para que apunte a un script PHP donde generaremos la página. En la siguiente petición a la misma página el Apache devolverá directamente el archivo HTML generado.</p>
<p>Algunas consideraciones previas:</p>
<ul>
<li>Necesitas tener permisos de escritura en el directorio donde pretendas guardar las páginas. (esto lo puedes conseguir fijando los permisos a 777).
<li>Necesitas poder configurar la directiva <em>ErrorDocument</em> de tu servidor Apache. (algunos hostings no lo permiten).</li>
</ul>
<p><strong>[1] Configurar el Apache</strong></p>
<p>Debemos añadir lo siguiente en nuestro <em>.htaccess</em> o en la configuración del servidor Apache:</p>
<p><code>ErrorDocument 404 genera_pagina.php</code></p>
<p><strong>[2] Añadir el código necesario</strong></p>
<p>Es necesario añadir un bloque de código al principio y al fin de cada script. A continuación una implementación de ejemplo:</p>
<div class="syntax_hilite">
<div id="php-3">
<div class="php"><span style="color:#FF9933; font-style:italic;">//obtenemos el nombre de la página solicitada</span><br />
<span style="color:#0000FF;">$pagina</span> = <a href="http://www.php.net/array_pop"><span style="color:#000066;">array_pop</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/explode"><span style="color:#000066;">explode</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'/'</span>,<span style="color:#0000FF;">$_SERVER</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#FF0000;">'REQUEST_URI'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">//iniciamos el output buffer</span><br />
<a href="http://www.php.net/ob_start"><span style="color:#000066;">ob_start</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">//.............................</span><br />
<span style="color:#FF9933; font-style:italic;">//código que genera la página</span><br />
<a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#FF0000;">'hola'</span>;<br />
<span style="color:#FF9933; font-style:italic;">//.............................</span><br />
<span style="color:#FF9933; font-style:italic;">//obtenemos el output bufer</span><br />
<span style="color:#0000FF;">$contenido</span> = <a href="http://www.php.net/ob_get_contents"><span style="color:#000066;">ob_get_contents</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">//guardamos la pagina estática</span><br />
file_put_contents<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$pagina</span>,<span style="color:#0000FF;">$contenido</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">//volcamos por pantalla y cerramos el output buffer</span><br />
<a href="http://www.php.net/ob_end_flush"><span style="color:#000066;">ob_end_flush</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Se puede guardar el anterior código en un script llamado "genera_pagina.php" sustituyendo la linea <em>echo "hola"</em> por el código de nuestra aplicación (p.e. con un <em>include()</em>) o podemos dividir el código en dos scripts y usar las directivas <a target="_blank" href="http://es2.php.net/manual/es/ini.core.php#ini.auto-append-file" title="auto-append-file - PHP: Descripción de las directivas de núcleo en php.ini - Manual">auto-append-file</a> y <a target="_blank" href="http://es2.php.net/manual/es/ini.core.php#ini.auto-prepend-file" title="auto-prepend-file - PHP: Descripción de las directivas de núcleo en php.ini - Manual">auto-prepend-file</a> para no tener que modificar nuestra aplicación (cortar por las lineas de puntos).</p>
<p>En el ejemplo se obtiene sólo el nombre de la página solicitada y se crea una archivo con el mismo nombre con el contenido de la respuesta. Pero no soporta directorios, está pensado para trabajar sobre un directorio en concreto o en una web sin directorios en las URL. Cambiando la primera linea del ejemplo podéis hacer que se comporte de otra forma, el ejemplo simplemente obtiene el último trozo de la URL usando como delimitador "/".</p>
<p>A diferencia de otras propuestas de cache aquí estamos modificando el Apache para que ejecute un script en caso de no encontrar una página. Es por esto que en vuestra aplicación debéis generar una <strong>página de error</strong> en el caso de que la página solicitada no exista. Lo correcto es que en esta página de error se envíe la header correspondiente tal y como lo haría el Apache por defecto:</p>
<div class="syntax_hilite">
<div id="php-4">
<div class="php"><a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"HTTP/1.0 404 Not Found"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p><strong>[3] Mantenimiento de la cache</strong></p>
<p>Por ultimo nos falta programar un proceso en el cron para que elimine los archivos de la cache que han caducado. Por ejemplo para mantener una cache de una hora:</p>
<p><code>0 * * * * find /web -mtime +1h -print0 | xargs -0 rm -f</code></p>
<p>Se ha de sustituir "/web" por la ruta física donde tenemos nuestra aplicación web. Si no queremos programar un cron siempre podemos hacer lo anterior desde algún script PHP que se ejecute constantemente en nuestra web.</p>
<p>Lo que comento en este post no es nada nuevo, ya fue propuesto por <a target="_blank" href="http://www.lerdorf.com/tips.pdf" title="Tips and Tricks PHPCon2002">Rasmus Lerdorf en el PHPCon del 2002</a> (aunque un poco caducada la presentación que enlazo merece la pena).</p>


<p>Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li><li><a href='http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/' rel='bookmark' title='Permanent Link: Instalación del APC (Alternative PHP Cache) sobre FreeBSD'>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</a></li><li><a href='http://www.phpbsd.net/2007/07/12/nuevos-estandares-para-las-pear2/' rel='bookmark' title='Permanent Link: Nuevos estándares para las PEAR2'>Nuevos estándares para las PEAR2</a></li></ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.phpbsd.net/2007/05/16/cache-de-paginas-estaticas-para-php/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Cache en memoria compartida con APC</title>
		<link>http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/</link>
		<comments>http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/#comments</comments>
		<pubDate>Wed, 02 May 2007 18:37:23 +0000</pubDate>
		<dc:creator>Oriol</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[memoria-compartida]]></category>
		<category><![CDATA[objetos]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[webmaster]]></category>

		<guid isPermaLink="false">http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/</guid>
		<description><![CDATA[Como continuación del anterior post voy a explicar brevemente como montar una cache de objetos en memoria compartida usando APC. Esto nos permite disponer de una cache accesible para cualquier proceso Apache que se esté ejecutando en el servidor. Podemos guardar cualquier variable (resultados de queries, páginas html, cualquier tipo de objeto, etc.) y esta [...]


Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/' rel='bookmark' title='Permanent Link: Instalación del APC (Alternative PHP Cache) sobre FreeBSD'>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</a></li><li><a href='http://www.phpbsd.net/2007/05/16/cache-de-paginas-estaticas-para-php/' rel='bookmark' title='Permanent Link: Cache de páginas estáticas para PHP'>Cache de páginas estáticas para PHP</a></li><li><a href='http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/' rel='bookmark' title='Permanent Link: Optimización del rendimiento de ADOdb en PHP'>Optimización del rendimiento de ADOdb en PHP</a></li></ul>]]></description>
			<content:encoded><![CDATA[<p>Como continuación del anterior post voy a explicar brevemente como montar una <strong>cache de objetos en memoria compartida</strong> usando <a target="_blank" href="http://www.php.net/manual/en/ref.apc.php" title="PHP: Alternative PHP Cache - Manual">APC</a>. Esto nos permite disponer de una cache accesible para cualquier proceso Apache que se esté ejecutando en el servidor. Podemos guardar cualquier variable (resultados de queries, páginas html, cualquier tipo de objeto, etc.) y esta se conservará entre las distintas peticiones hasta que la borremos de cache o expire el TTL que queramos.</p>
<p>Una forma rápida de ver su uso es con un ejemplo:</p>
<div class="syntax_hilite">
<div id="php-7">
<div class="php"><span style="color:#0000FF;">$obj</span> = <span style="color:#000000; font-weight:bold;">new</span> Objeto<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
apc_store<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'key'</span>,<a href="http://www.php.net/serialize"><span style="color:#000066;">serialize</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$obj</span><span style="color:#006600; font-weight:bold;">&#41;</span>,<span style="color:#CC66CC;">3600</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$result</span> = <a href="http://www.php.net/unserialize"><span style="color:#000066;">unserialize</span></a><span style="color:#006600; font-weight:bold;">&#40;</span>apc_fetch<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'key'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<a href="http://www.php.net/var_dump"><span style="color:#000066;">var_dump</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$result</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Usando <a target="_blank" href="http://www.php.net/manual/en/function.apc-store.php" title="PHP: apc_store - Manual">apc_store()</a> guardamos <em>$obj</em> en cache durante una hora. Podemos recuperar o borrar <em>$obj</em> de la cache usando el identificador <em>key</em>. Es necesario realizar serialize/unserialize si guardamos datos como objetos o arrays, para variables simples no es necesario.</p>
<p>Para borrar el anterior objeto de cache:</p>
<div class="syntax_hilite">
<div id="php-8">
<div class="php">apc_delete<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'key'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Para evitar el uso de <em>define</em> el cual es bastante lento disponemos de <a target="_blank" href="http://www.php.net/manual/en/function.apc-define-constants.php" title="PHP: apc_define_constants - Manual">apc_define_constants()</a> y <a target="_blank" href="http://www.php.net/manual/en/function.apc-load-constants.php" title="PHP: apc_load_constants - Manual">apc_load_constants()</a> para guardar y recuperar constantes de cache.</p>
<p>El APC ofrece una interfaz gráfica para ver el uso que hacemos de la cache, que opciones tenemos activas, archivos "compilados", variables almacenadas, etc. a la vez que nos permite borrar todo el contenido de la cache. Podemos obtener la misma información con la función <a target="_blank" href="http://www.php.net/manual/en/function.apc-cache-info.php" title="PHP: apc_cache_info - Manual">apc_cache_info()</a> y para borrar la cache tenemos <a target="_blank" href="http://www.php.net/manual/en/function.apc-clear-cache.php" title="PHP: apc_clear_cache - Manual">apc_clear_cache()</a> aunque la interfaz gráfica no deja de ser interesante.</p>
<p>Un snapshot de ejemplo:</p>
<p><img src="http://www.phpbsd.net/wp-content/images/snapshot_apc.png" alt="APC snapshot" /></p>
<p>Para instalarla en FreeBSD se trata de copiar el archivo <em>/usr/local/share/doc/APC/apc.php</em> en algún lugar dentro de nuestro document root del Apache.</p>


<p>Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/' rel='bookmark' title='Permanent Link: Instalación del APC (Alternative PHP Cache) sobre FreeBSD'>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</a></li><li><a href='http://www.phpbsd.net/2007/05/16/cache-de-paginas-estaticas-para-php/' rel='bookmark' title='Permanent Link: Cache de páginas estáticas para PHP'>Cache de páginas estáticas para PHP</a></li><li><a href='http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/' rel='bookmark' title='Permanent Link: Optimización del rendimiento de ADOdb en PHP'>Optimización del rendimiento de ADOdb en PHP</a></li></ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</title>
		<link>http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/</link>
		<comments>http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/#comments</comments>
		<pubDate>Thu, 26 Apr 2007 21:10:58 +0000</pubDate>
		<dc:creator>Oriol</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[apc]]></category>
		<category><![CDATA[bsd]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[freebsd]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[webmaster]]></category>

		<guid isPermaLink="false">http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/</guid>
		<description><![CDATA[Como prometía en el post dedicado a la optimización de ADOdb voy a explicar como instalar el sistema de cache APC sobre un servidor FreeBSD 6.x. El APC (Alternative PHP Cache) es un sistema de cache de opcode para PHP, sirve para cachear el código intermedio del PHP y así no tener que interpretar todos [...]


Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li><li><a href='http://www.phpbsd.net/2006/09/22/la-primera-beta-del-freebsd-62-ya-esta-disponible/' rel='bookmark' title='Permanent Link: La primera beta del FreeBSD 6.2 ya está disponible'>La primera beta del FreeBSD 6.2 ya está disponible</a></li><li><a href='http://www.phpbsd.net/2006/07/27/terminadas-las-elecciones-del-nuevo-core-team-del-freebsd/' rel='bookmark' title='Permanent Link: Terminadas las elecciones del nuevo Core Team del FreeBSD'>Terminadas las elecciones del nuevo Core Team del FreeBSD</a></li></ul>]]></description>
			<content:encoded><![CDATA[<p>Como prometía en el post dedicado a la <a href="http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/" title="Optimización del rendimiento de ADOdb en PHP en PHPBSD.net">optimización de ADOdb</a> voy a explicar como instalar el sistema de cache <strong>APC sobre un servidor FreeBSD 6.x</strong>. El <a target="_blank" href="http://www.php.net/manual/en/ref.apc.php" title="PHP: Alternative PHP Cache - Manual">APC</a> (Alternative PHP Cache) es un sistema de cache de <a target="_blank" href="http://en.wikipedia.org/wiki/Opcode" title="Opcode - Wikipedia, the free encyclopedia">opcode</a> para PHP, sirve para cachear el código intermedio del PHP y así no tener que interpretar todos los scripts en cada ejecución. Para almacenar este código "compilado" se usa la memoria compartida del sistema. A parte el APC nos ofrece funciones para poder almacenar y recuperar datos de cache.</p>
<p>El APC es una extensión <a target="_blank" href="http://pecl.php.net/package/apc" title="PECL :: Package :: APC">PECL</a> que no viene incluida por defecto con el PHP (esto cambiará con la futura versión 6). A continuación describo como instalar y configurar el APC sobre FreeBSD.</p>
<p><strong>[1] Instalar el port</strong></p>
<p>Suponiendo que tenemos instalado y funcionando un servidor web (Apache+PHP) sólo nos falta añadirle la extensión PECL con:</p>
<p><code># portinstall pecl-APC</code></p>
<p>Si no trabajas con portupgrade:</p>
<p><code># cd /usr/ports/www/pecl-APC/<br />
# make install clean</code></p>
<p>Con esto compilamos e instalamos el APC. Si todo va bien acabará el proceso y podremos ver esta nueva linea en el archivo <em>/usr/local/etc/php/extensions.ini</em>:</p>
<p><code>extension=apc.so</code></p>
<p>Cuando lo compilas se dan a escoger tres opciones: MMAP, SEMAPHORES y PHP4_OPT. Es aconsejable seleccionar sólo MMAP y si trabajas con PHP4 la última también. La opción de SEMAPHORES dependiendo de tu sistema puede provocar cierta inestabilidad y no ofrece muchas mejoras en rendimiento.</p>
<p>La última versión del APC (pecl-APC-3.0.14) se compila siempre con soporte mmap aunque desactives la opción (o esto es lo que me pasa a mi en los servidores bajo FreeBSD).</p>
<p>Ahora sólo falta configurar correctamente las directivas apropiadas en el php.ini y un restart (o reload) del Apache.</p>
<p><strong>[2] Configurando el APC</strong></p>
<p>La configuración por defecto del APC es apropiada en muchas situaciones aunque bajo FreeBSD deberíamos configurar correctamente el tamaño de memoria compartida. Esto se consigue con las siguientes directivas:</p>
<p><code>apc.shm_segments=1<br />
apc.shm_size=32</code></p>
<p>En FreeBSD el tamaño de memoria compartida por defecto es de 32MB. Puedes optar por aumentarlo o por dejarlo igual y usar varios segmentos configurando la directiva <em>apc.shm_segments</em>. Para aumentar el tamaño de la memoria compartida a 128MB en FreeBSD:</p>
<p><code># sysctl kern.ipc.shmmax=134217728<br />
# sysctl kern.ipc.shmall=32768</code></p>
<p>Si quieres conservar estos valores después de reiniciar el sistema debes añadirlos en <em>/etc/sysctl.conf</em>.</p>
<p>Se debe fijar SHMALL (kern.ipc.shmall) a SHMMAX/PAGE_SIZE. Este valor en el ejemplo descrito de 128MB de memoria compartida nos queda como: 134217728/4096 = 32768. Puedes ejecutar el comando <em>pagesize</em> para conocer el tamaño de una página de memoria (PAGE_SIZE) en tu sistema y <em>ipcs -M</em> para verificar la configuración de la memoria compartida.</p>
<p>También hacer notar en este punto que con la última versión del APC bajo FreeBSD no permite usar varios segmentos de memoria compartida y estás obligado a sólo usar un segmento, si necesitas más memoria debes aumentar el tamaño de memoria compartida del sistema.</p>
<p>El resto de directivas de configuración dependen mucho del tipo de aplicación PHP. Dependiendo del número de visitas, cantidad de archivos a cachear, frecuencia de cambio de los archivos, etc. Una configuración de ejemplo con pequeñas notas acerca del significado de las directivas usadas (en el archivo <em>/usr/local/share/doc/APC/INSTALL</em> tienes todas las directivas disponibles detalladas):</p>
<p><code>; Activa el APC<br />
apc.enabled=1<br />
; Número de segmentos de memoria compartida<br />
apc.shm_segments=1<br />
; Tamaño de la memoria compartida<br />
apc.shm_size=128<br />
; Un número aproximado de archivos fuente a cachear<br />
apc.num_files_hint=6000<br />
; Un número aproximado de variables a cachear<br />
apc.user_entries_hint=100<br />
; Segundos que dejamos en cache una entrada que ya no se usa<br />
apc.ttl=600<br />
; Idem al anterior pero para las variables de usuario<br />
apc.user_ttl=600<br />
; Segundos que dejamos una entrada cacheada en el recolector de basura<br />
apc.gc_ttl=0<br />
; Indica si se cachea por defecto.<br />
apc.cache_by_default=On<br />
; Expresiones regulares para saber que archivos cacheamos<br />
; Resulta útil si se usa en combinación con la directiva anterior<br />
apc.filters=""<br />
; Indica si se activa el APC para el modo CLI del PHP<br />
apc.enable_cli=0<br />
; Indica el tamaño máximo de archivos a cachear<br />
apc.max_file_size=1M<br />
; Indica si el APC ha de verificar si los archivos han sido modificados<br />
; para actualizar la cache<br />
apc.stat=1</code></p>
<p>De todos los cacheadores de código que he usado APC es con diferencia el más estable aunque no es perfecto. En situaciones de mucho tráfico y si constantemente estás cambiando los archivos al final consigues un fantástico <a target="_blank" href="http://en.wikipedia.org/wiki/Segmentation_fault" title="Segmentation fault - Wikipedia, the free encyclopedia">segfault</a> del Apache. Una gran opción si dispones de una aplicación que no está en constante desarrollo es usar la directiva <em>apc.stat</em> a 0, con este parámetro consigues mucha más estabilidad.</p>
<p>Es un gran invento y es muy recomendable su uso, puedes llegar a ver loads de CPU reducidos al 50% y ganar un 20% de memoria. Pero como todo tiene bugs y al menos yo en el escenario donde lo uso (decenas de millones de páginas vistas por mes + clúster de decenas de servidores BSD) es un tanto inestable en ciertas situaciones... pero mucho más estable que algo como EAccelerator el cual en el anterior escenario no aguanta ni 5 minutos.</p>
<p>Si usas APC sobre FreeBSD en webs con mucho tráfico y no tienes ni un segfault nunca... no te cortes y comenta que directivas/opciones estás usando.</p>
<p>En un siguiente post explicaré como usar las funciones que proporciona el APC para almacenar datos de aplicación en cache.</p>


<p>Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li><li><a href='http://www.phpbsd.net/2006/09/22/la-primera-beta-del-freebsd-62-ya-esta-disponible/' rel='bookmark' title='Permanent Link: La primera beta del FreeBSD 6.2 ya está disponible'>La primera beta del FreeBSD 6.2 ya está disponible</a></li><li><a href='http://www.phpbsd.net/2006/07/27/terminadas-las-elecciones-del-nuevo-core-team-del-freebsd/' rel='bookmark' title='Permanent Link: Terminadas las elecciones del nuevo Core Team del FreeBSD'>Terminadas las elecciones del nuevo Core Team del FreeBSD</a></li></ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Creando imágenes on-the-fly con las GD en PHP</title>
		<link>http://www.phpbsd.net/2007/03/15/creando-imagenes-on-the-fly-con-las-gd-en-php/</link>
		<comments>http://www.phpbsd.net/2007/03/15/creando-imagenes-on-the-fly-con-las-gd-en-php/#comments</comments>
		<pubDate>Thu, 15 Mar 2007 03:12:39 +0000</pubDate>
		<dc:creator>Oriol</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[gd]]></category>
		<category><![CDATA[imágenes]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[webmaster]]></category>

		<guid isPermaLink="false">http://www.phpbsd.net/2007/03/15/creando-imagenes-on-the-fly-con-las-gd-en-php/</guid>
		<description><![CDATA[GD es una librería de código abierto para la creación dinámica de imágenes. GD está escrita en C aunque puede ser usada desde varios lenguajes de programación entre ellos, como no, nuestro querido PHP.
A continuación describo como generar imágenes GIF "on the fly" usando PHP. Se puede usar este código para generar botones bajo demanda [...]


Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/01/28/usando-mod_rewrite-y-feedburner-para-las-feeds-de-un-blog-con-wordpress/' rel='bookmark' title='Permanent Link: Usando mod_rewrite y FeedBurner para las feeds de un blog con WordPress'>Usando mod_rewrite y FeedBurner para las feeds de un blog con WordPress</a></li><li><a href='http://www.phpbsd.net/2007/02/09/leyendo-xml-desde-php-con-simplexml/' rel='bookmark' title='Permanent Link: Leyendo XML desde PHP con SimpleXML'>Leyendo XML desde PHP con SimpleXML</a></li><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li></ul>]]></description>
			<content:encoded><![CDATA[<p><a target="_blank" href="http://www.boutell.com/gd/" title="GD Graphics Library">GD</a> es una librería de código abierto para la <strong>creación dinámica de imágenes</strong>. GD está escrita en C aunque puede ser usada desde varios lenguajes de programación entre ellos, como no, nuestro querido PHP.</p>
<p>A continuación describo como generar imágenes <a target="_blank" href="http://es.wikipedia.org/wiki/Gif" title="Graphics Interchange Format - Wikipedia, la enciclopedia libre">GIF</a> "on the fly" usando PHP. Se puede usar este código para generar botones bajo demanda lo que resulta muy útil en distintas ocasiones, por ejemplo en webs que pretender ser traducidas a varios idiomas.</p>
<div class="syntax_hilite">
<div id="php-13">
<div class="php"><span style="color:#000000; font-weight:bold;">function</span> genera_boton<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$text</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; <a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"Content-type: image/gif"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#0000FF;">$font</span> = <span style="color:#FF0000;">'../fonts/ARIALNB.TTF'</span>;<br />
&nbsp; <span style="color:#0000FF;">$fontsize</span> = <span style="color:#CC66CC;">11</span>;<br />
&nbsp; <span style="color:#0000FF;">$ycoord</span> = <span style="color:#CC66CC;">17</span>;<br />
&nbsp; <span style="color:#0000FF;">$imgheight</span> = <span style="color:#CC66CC;">22</span>;<br />
&nbsp; <span style="color:#0000FF;">$xpad</span> = <span style="color:#CC66CC;">40</span>;<br />
&nbsp; <span style="color:#0000FF;">$details</span> = imageftbbox<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$fontsize</span>, <span style="color:#CC66CC;">0</span>, <span style="color:#0000FF;">$font</span>, <span style="color:#0000FF;">$text</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#0000FF;">$imgwidth</span> = <a href="http://www.php.net/abs"><span style="color:#000066;">abs</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$details</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC66CC;">2</span><span style="color:#006600; font-weight:bold;">&#93;</span> - <span style="color:#0000FF;">$details</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC66CC;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> + <span style="color:#0000FF;">$xpad</span>;<br />
&nbsp; <span style="color:#0000FF;">$xcoord</span> = <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$imgwidth</span> - <span style="color:#0000FF;">$details</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC66CC;">4</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> / <span style="color:#CC66CC;">2</span>;<br />
&nbsp; <span style="color:#0000FF;">$im</span> = @imagecreate<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$imgwidth</span>, <span style="color:#0000FF;">$imgheight</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; or <a href="http://www.php.net/die"><span style="color:#000066;">die</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'error generando la imagen'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#0000FF;">$background_color</span> = imagecolorallocate<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$im</span>, <span style="color:#CC66CC;">0</span>, <span style="color:#CC66CC;">0</span>, <span style="color:#CC66CC;">128</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#0000FF;">$text_color</span> = imagecolorallocate<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$im</span>, <span style="color:#CC66CC;">255</span>, <span style="color:#CC66CC;">255</span>, <span style="color:#CC66CC;">255</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; imagettftext<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$im</span>,<span style="color:#0000FF;">$fontsize</span>,<span style="color:#CC66CC;">0</span>,<span style="color:#0000FF;">$xcoord</span>,<span style="color:#0000FF;">$ycoord</span>,<span style="color:#0000FF;">$text_color</span>,<span style="color:#0000FF;">$font</span>,<span style="color:#0000FF;">$text</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; imagegif<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$im</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; imagedestroy<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$im</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#006600; font-weight:bold;">&#125;</span><br />
genera_boton<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">'HOLA MUNDO'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>La imagen generada es muy simple y sólo debería servir de ejemplo, aunque con pocos retoques se puede conseguir algo mucho más bonito. La función genera un rectángulo azul con el texto <em>$text</em> centrado, se usa la fuente TrueType ARIALNB.TTF (disponible en cualquier Güindows).</p>
<p>Mediante la información devuelta por <a target="_blank" href="http://www.php.net/manual/en/function.imagettfbbox.php" title="PHP: imagettfbbox - Manual">imageftbbox()</a> se centra el texto automáticamente pero la altura de la imagen y la posición vertical del texto se fijan manualmente. Esto es así ya que si calculamos estos valores (<em>$imgheight</em> y <em>$ycoord</em>) pueden variar de forma no deseada dependiendo de la fuente usada y del texto que queremos mostrar, por ejemplo con el uso de acentos, mayúsculas o eñes obtendríamos imágenes con una altura mayor... y normalmente uno quiere que todos los botones tengan la misma altura :)</p>
<p>Si usas otra fuente o tamaño de fuente tendrás que ajustar los valores <em>$ycoord</em> e <em>$imgheight</em>. Probablemente también quieras ajustar <em>$xpad</em> que es lo que fija los márgenes izquierdo y derecho entre el texto y el borde de la imagen.</p>
<p>Paso a tratar un tema habitual en este blog, el <strong>rendimiento</strong>. Es muy interesante utilizar algún tipo de <strong>cache</strong> de los botones generados, a continuación propongo un par de ideas de cache (cliente y servidor):</p>
<p><strong>[1]</strong> Usando el segundo parámetro de <a target="_blank" href="http://www.php.net/manual/en/function.imagegif.php" title="PHP: imagegif - Manual">imagegif()</a> <strong>guardar en disco el archivo</strong> GIF. Entonces podemos tirar de <em>is_file()</em> para comprobar si ya disponemos del GIF generado que con un simple <em>file_get_contents()</em> podremos recuperar. Aunque es mucho más óptimo configurar reglas de <a target="_blank" href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html" title="mod_rewrite - Apache HTTP Server">mod_rewrite</a> del Apache para devolver el GIF directamente en caso de que exista el archivo.</p>
<p><strong>[2]</strong> Enviar las <strong>headers de cache</strong> apropiadas al navegador del usuario. Por ejemplo tendremos cache de una semana añadiendo lo siguiente al inicio del código anterior:</p>
<div class="syntax_hilite">
<div id="php-14">
<div class="php"><a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"Expires: "</span>.<a href="http://www.php.net/gmdate"><span style="color:#000066;">gmdate</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"D, d M Y H:i:s"</span>, <a href="http://www.php.net/mktime"><span style="color:#000066;">mktime</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"H"</span><span style="color:#006600; font-weight:bold;">&#41;</span>,<a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"i"</span><span style="color:#006600; font-weight:bold;">&#41;</span>,<a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"s"</span><span style="color:#006600; font-weight:bold;">&#41;</span>,<a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"m"</span><span style="color:#006600; font-weight:bold;">&#41;</span>,<a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"d"</span><span style="color:#006600; font-weight:bold;">&#41;</span>+<span style="color:#CC66CC;">7</span>,<a href="http://www.php.net/date"><span style="color:#000066;">date</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"Y"</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#FF0000;">"GMT"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<a href="http://www.php.net/header"><span style="color:#000066;">header</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"Last-Modified: "</span>.<a href="http://www.php.net/gmdate"><span style="color:#000066;">gmdate</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#FF0000;">"D, d M Y H:i:s"</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#FF0000;">"GMT"</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Para finalizar añadir que puedes generar botones más bonitos usando <em>imagecreatefrompng()</em> para cargar imágenes que sirvan de plantilla. Otra opción es con funciones como <em>imagepolygon()</em> y <em>imagerectangle()</em> dedicar un buen rato a diseñar pero con PHP :)</p>
<p>Como no soy muy de diseño (ni con las GD), si alguien se ha currado botones más bonitos usando <strong>sólo funciones GD</strong> o sabe sitios donde encontrarlos... q no se corte!</p>


<p>Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/01/28/usando-mod_rewrite-y-feedburner-para-las-feeds-de-un-blog-con-wordpress/' rel='bookmark' title='Permanent Link: Usando mod_rewrite y FeedBurner para las feeds de un blog con WordPress'>Usando mod_rewrite y FeedBurner para las feeds de un blog con WordPress</a></li><li><a href='http://www.phpbsd.net/2007/02/09/leyendo-xml-desde-php-con-simplexml/' rel='bookmark' title='Permanent Link: Leyendo XML desde PHP con SimpleXML'>Leyendo XML desde PHP con SimpleXML</a></li><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li></ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.phpbsd.net/2007/03/15/creando-imagenes-on-the-fly-con-las-gd-en-php/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Optimización del rendimiento de ADOdb en PHP</title>
		<link>http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/</link>
		<comments>http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/#comments</comments>
		<pubDate>Wed, 06 Dec 2006 03:39:20 +0000</pubDate>
		<dc:creator>Oriol</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[adodb]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[webmaster]]></category>

		<guid isPermaLink="false">http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/</guid>
		<description><![CDATA[ADOdb es una librería de abstracción de base de datos para PHP muy potente. Dispone de una cantidad de usuarios y casos de éxito importante y ofrece muchas funcionalidades interesantes con soporte para una buena lista de engines de BD. Es un proyecto maduro, iniciado el año 2000, que si no conoces se merece una [...]


Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/' rel='bookmark' title='Permanent Link: Instalación del APC (Alternative PHP Cache) sobre FreeBSD'>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</a></li><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li><li><a href='http://www.phpbsd.net/2008/04/11/optimizacion-de-aplicaciones-php-server-side/' rel='bookmark' title='Permanent Link: Optimización de aplicaciones PHP (server side)'>Optimización de aplicaciones PHP (server side)</a></li></ul>]]></description>
			<content:encoded><![CDATA[<p>ADOdb es una librería de abstracción de base de datos para PHP muy potente. Dispone de una cantidad de usuarios y casos de éxito importante y ofrece muchas funcionalidades interesantes con soporte para una buena lista de engines de BD. Es un proyecto maduro, iniciado el año 2000, que si no conoces se merece una ojeada en su <a title="ADOdb Database Abstraction Library for PHP (and Python)" target="_blank" href="http://adodb.sourceforge.net/">página oficial</a>.</p>
<p>Como consecuencia de la cantidad de funcionalidades que ofrece es un layer tirando a lento (existen alternativas más rápidas y limpias). Esto es debido a que es un proyecto enorme con miles de lineas de código algunas de ellas, desgraciadamente, de no mucha calidad. Aunque a mi personalmente me gusta mucho y en todo proyecto software existen algunas partes un poco feas.</p>
<p>Dependiendo de la carga del site donde uses ADOdb o dependiendo de si necesitas todas sus funcionalidades es aconsejable estudiar bien otras alternativas mucho más lights. Como <a title="ADOdb Lite" target="_blank" href="http://adodblite.sourceforge.net/index.php">ADOdbLite</a> (simulando ADOdb pero mucho más optimizada y con muchas menos funcionalidades), <a target="_blank" title="The PHP Data Objects (PDO) extension" href="http://www.php.net/manual/en/ref.pdo.php">PDO</a> (dispone de las características más importantes de ADOdb, es más rápida y se ha convertido en el estándar), <a title="PEAR MDB2" target="_blank" href="http://pear.php.net/package/MDB2">PEAR MDB2</a> (sucesora de la clásica DB, potente y bastante rápida). Según John Lim, ADOdb no es que sea tan lenta, pero si la usas en un site con bastante carga y no realizas ninguna de las optimizaciones aquí descritas puedes estar perdiendo unos cuantos segundos en el total de una sesión de usuario (decenas o centenares de ms por página), y muchísimos más si entramos en el tema del uso de la cache de queries (que con esto ADOdb no es precisamente el culpable sino que proporciona un sistema de cache para el acceso a BD).</p>
<p>Es cierto que ADOdb arrasa en funcionalidades sobre las tres alternativas que he comentado pero como en muchas situaciones en el desarrollo en PHP vale la pena valorar las funcionalidades versus rendimiento. Estudiar bien el uso que le vamos a dar a la librería, la carga del site. frecuencia de las queries (dependiendo del tipo de web o de si disponemos de caches de contenido), etc.</p>
<p>Si a pesar de lo anterior te encanta ADOdb y lo quieres utilizar o si ya lo usas en algún proyecto y no puedes asumir un cambio, aquí van algunos consejos para mejorar el rendimiento del acceso a BD (optimizaciones para la librería y como usar la cache de queries).</p>
<p><strong>[1]</strong> Usar la extensión de C de ADOdb. Si la instalas la librería PHP del ADOdb se encargará de usarla, aunque también puedes usar directamente las funciones adodb_* en tu código. Puedes descargarla <a title="Download adodb-ext-504.zip" target="_blank" href="http://phplens.com/lens/dl/adodb-ext-504.zip">aquí</a>, dentro del archivo están las instrucciones para su instalación (archivo README.txt).</p>
<p><strong>[2]</strong> Sobretodo, si tiras de la versión PHP de la librería usar un acelerador de código con opcode cache. Como <a title="The Alternative PHP Cache (APC)" target="_blank" href="http://www.php.net/manual/en/ref.apc.php">APC</a> o <a title="eAccelerator: PHP Accelerator, optimizer, dynamic content cache - Trac" target="_blank" href="http://eaccelerator.net/">EAccelerator</a>. Con sites con mucha carga, por mi experiencia personal, APC lo considero un sistema mucho más estable que el EA. El APC se instala como una extensión PECL del PHP.</p>
<p><strong>[3]</strong> Usar la cache de ADOdb para tus queries. Esto se consigue con el uso de CacheExecute(). De las queries ejecutadas con este método se almacenan los recordsets devueltos a disco, esto es, con las siguientes queries idénticas el ADOdb devuelve el objeto serializado de disco hasta que no caduque.</p>
<p>Para poder usar CacheExecute() es necesario crear un directorio para la cache e iniciar el ADOdb como sigue:</p>
<div class="syntax_hilite">
<div id="php-19">
<div class="php"><span style="color:#0000FF;">$ADODB_CACHE_DIR</span> = <span style="color:#FF0000;">'/var/directorio_para_la_cache'</span>;<br />
<span style="color:#0000FF;">$db</span> = NewADOConnection<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$dsn</span>.<span style="color:#FF0000;">'/'</span>.<span style="color:#0000FF;">$dbname</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">SetFetchMode</span><span style="color:#006600; font-weight:bold;">&#40;</span>ADODB_FETCH_ASSOC<span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Para lanzar una query almacenando cache durante un día:</p>
<div class="syntax_hilite">
<div id="php-20">
<div class="php">try <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; <span style="color:#0000FF;">$sql</span> = <span style="color:#FF0000;">'SELECT id FROM datos WHERE nombre=&quot;'</span>.<span style="color:#0000FF;">$n</span>.<span style="color:#FF0000;">'&quot;'</span>;<br />
&nbsp; <span style="color:#0000FF;">$rs</span>=<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">CacheExecute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC66CC;">86400</span>,<span style="color:#0000FF;">$sql</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#FF9933; font-style:italic;">// ...</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span> catch <span style="color:#006600; font-weight:bold;">&#40;</span>ADODB_Exception <span style="color:#0000FF;">$e</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; <span style="color:#FF9933; font-style:italic;">// ...</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
<p>Contando claro que trabajamos con PHP5 y que hemos cargado el soporte para exceptions del ADOdb. Esto se consigue añadiendo:</p>
<div class="syntax_hilite">
<div id="php-21">
<div class="php"><span style="color:#616100;">require_once</span> <span style="color:#FF0000;">'adodb/adodb-exceptions.inc.php'</span>;</div>
</div>
</div>
<p></p>
<p><strong>[4]</strong> Es interesante valorar <a title="memcached: a distributed memory object caching system" target="_blank" href="http://www.danga.com/memcached/">memcached</a> como sustituto de la cache a disco por defecto. ADOdb incluye el código necesario para usarlo. Memcached es teóricamente más rápido que el acceso a los recordsets serializados a disco, aunque la principal ventaja que ofrece es la reutilización de la cache entre distintos servidores.</p>
<p>Una vez instalado memcached, para iniciarlo:</p>
<p><code># memcached -d -m 512 -l 127.0.0.1 -p 11211 -u www</code></p>
<p>Para iniciar el daemon con 512 MB de memoria escuchando sólo en localhost y corriendo como usuario www. Cambiar 127.0.0.1 por la IP de vuestro servidor tanto en el comando como en el código PHP que sigue, y www por el usuario que ejecute el Apache. Es necesario instalar una <a title="Memcache Functions" target="_blank" href="http://www.php.net/manual/en/ref.memcache.php">extensión PECL</a> para trabajar con memcached.</p>
<p>Para iniciar ADOdb y indicar que queremos usar memcached para nuestros CacheExecute:</p>
<div class="syntax_hilite">
<div id="php-22">
<div class="php"><span style="color:#0000FF;">$db</span> = NewADOConnection<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$dsn</span>.<span style="color:#FF0000;">'/'</span>.<span style="color:#0000FF;">$dbname</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">SetFetchMode</span><span style="color:#006600; font-weight:bold;">&#40;</span>ADODB_FETCH_ASSOC<span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">memCache</span> = <span style="color:#000000; font-weight:bold;">true</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">memCacheHost</span> = <span style="color:#FF0000;">'localhost'</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">memCachePort</span> = <span style="color:#CC66CC;">11211</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">memCacheCompress</span> = <span style="color:#000000; font-weight:bold;">false</span>;<br />
<span style="color:#0000FF;">$db</span>-&gt;<span style="color:#006600;">cacheSecs</span> = <span style="color:#CC66CC;">86400</span>;</div>
</div>
</div>
<p></p>
<p><strong>[5]</strong> Aunque bastante incómodo y en algunos casos peligroso (futuros ALTER TABLE) es más rápido acceder directamente a $recordset->fields mediante el ID numérico y fijar la variable $ADODB_FETCH_MODE = ADODB_FETCH_NUM.</p>
<p><strong>[6]</strong> Finalmente podemos mirar de ejecutar los métodos _Execute() y _query() para lanzar nuestras queries. Estos son métodos mucho más crudos. _Execute() a diferencia de Execute() no emula binding, p.e. necesario para usar Prepare() si nuestra BD no lo soporta nativamente. Por el otro lado _query() si que es mucho más limitado, a parte de no emular binding tampoco devuelve recordset y no tiene debugging.</p>
<p>Con todo lo anterior podemos tener ADOdb bastante más optimizado aunque si tenemos un nuevo proyecto por delante quizás lo más aconsejable es usar PDO dado que todo apunta a que se convertirá en el estándar a seguir para el acceso a base de datos en PHP.</p>
<p>Acerca del tema de la cache de queries, sin ánimo de alargar más el post, sólo decir que es mucho más óptimo usar memcached para cachear objetos que no cachear las queries necesarias para generar estos objetos... si disponemos de unos buenos sistemas de caches de contenido (p.e. squid) y un sistema de cache de objetos genérico (memcached) cachear las queries deja de ser tan importante aunque te ofrece otro nivel de cache para jugar.</p>
<p>En un siguiente post dedicado a los sistemas de cache en PHP explicaré con más detalles como trabajar con APC y Memcached sobre servidores FreeBSD.</p>


<p>Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/04/26/instalacion-del-apc-alternative-php-cache-sobre-freebsd/' rel='bookmark' title='Permanent Link: Instalación del APC (Alternative PHP Cache) sobre FreeBSD'>Instalación del APC (Alternative PHP Cache) sobre FreeBSD</a></li><li><a href='http://www.phpbsd.net/2007/05/02/cache-en-memoria-compartida-con-apc/' rel='bookmark' title='Permanent Link: Cache en memoria compartida con APC'>Cache en memoria compartida con APC</a></li><li><a href='http://www.phpbsd.net/2008/04/11/optimizacion-de-aplicaciones-php-server-side/' rel='bookmark' title='Permanent Link: Optimización de aplicaciones PHP (server side)'>Optimización de aplicaciones PHP (server side)</a></li></ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.phpbsd.net/2006/12/06/optimizacion-del-rendimiento-de-adodb-en-php/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

