<?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"
	>

<channel>
	<title>QuarkBlog &#187; PHP</title>
	<atom:link href="http://quarkblog.org/category/programacin/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://quarkblog.org</link>
	<description>If you can read this, you need another beer.</description>
	<pubDate>Thu, 07 Aug 2008 07:20:00 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<item>
		<title>El culebrón PDO v2</title>
		<link>http://quarkblog.org/2008/01/26/el-culebron-pdo-v2/</link>
		<comments>http://quarkblog.org/2008/01/26/el-culebron-pdo-v2/#comments</comments>
		<pubDate>Sat, 26 Jan 2008 18:43:21 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Software Libre]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2008/01/26/el-culebron-pdo-v2/</guid>
		<description><![CDATA[PDO es una de las muchas abstracciones de acceso a datos que existen en PHP que intenta unificar la manera en la que PHP habla con las bases de datos. La característica que diferencia a PDO del resto es que está escrito en C y no en PHP (con lo que utiliza drivers nativos y [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://es2.php.net/pdo">PDO</a> es una de las muchas abstracciones de acceso a datos que existen en PHP que intenta unificar la manera en la que PHP habla con las bases de datos. La característica que diferencia a PDO del resto es que está escrito en C y no en PHP (con lo que utiliza drivers nativos y esta enfocado en ser rápido y eficiente).</p>
<p>Wez Furlong quiere convertir a PDO en la manera estándar de acceso a datos para PHP, para ello ha estado rediseñando la arquitectura y los interfaces de <a href="http://news.php.net/php.pdo/1">&#8220;PDO versión 2&#8243;</a> para producir una especificación abierta en la que los fabricantes de bases de datos puedan construir drivers, ampliar y mejorar la cobertura de tests unitarios y mejorar los metadatos.</p>
<p>Para obtener la atención de los fabricantes, especialmente IBM, ha propuesto un <a href="http://www.php.net/~wez/pdo/PDO-CLA-Individual-12-07-07.pdf">Contributor License Agreement</a> para facilitar la inclusión de código por parte de las empresas privadas (existen problemas legales por la cesión de propiedad intelectual a un proyecto open source). Existe una versión para empresas y otra a título individual, y la licencia de PDO que es diferente a la de PHP. Wez también ha preparado un <a href="http://www.php.net/~wez/pdo/pdo-faq.txt">FAQ</a> sobre todas las cuestiones legales de este asunto.</p>
<p>Este movimiento ha causado sentimientos enfrentados dentro de la comunidad de desarrolladores de PHP: mientras que <a href="http://mysqldump.azundris.com/exit.php?url_id=615&#038;entry_id=75">Jay Pipes</a> (MySQL) opina que no es para tanto, hay <a href="http://blog.thepimp.net/index.php/post/2008/01/24/Say-NO-to-CLA-in-PHP">otras</a> muchas personas que han puesto el grito en el cielo. Y es que el conflicto está en que todo aquel que quiera aportar código a PDOv2 o simplemente leer la especificación debe firmar el CLA y atenerse a sus condiciones. Lo que lo convierte en esencia en software no-libre.</p>
<p>PHP no es GPL (su licencia es incompatible) pero es considerado software libre. El requisito de firmar una CLA antes de remitir código o mirar la especificación de PDO v2 elimina directamente la libertad 3 (libertad para mejorar el programa y distribuir cambios al público, por los que se beneficia toda la comunidad), haciendo a PDO no-libre.</p>
<p>Dado que la GPL no se aplica a PHP ni a PDO, veamos la <a href="http://www.opensource.org/docs/osd">definición de software libre</a> que proporciona la OSI que es más o menos lo que viene a decir el <a href="http://www.debian.org/social_contract">contrato social de Debian</a> haciéndolo un poco más universal. Aquí ya me pierdo un poco (no soy abogado y es posible que me equivoque en muchas de estas cosas) pero creo que la obligación de firmar una CLA viola el espíritu de la definición de la OSI así como los puntos 3 y 5 de la carta.</p>
<p>La inclusión de CLAs es algo nuevo en el mundo de PHP pero es habitual e inevitable en otros proyectos de gran calado e importancia empresarial como Apache o Mozilla. El software libre no es sólo código abierto, es participación y las CLAs ponen trabas al libre intercambio de información porque determinadas empresas podrían influir negativamente en el desarrollo de PDO desplegando su cartera de patentes y segmentaría a los desarrolladores en dos grupos irreconciliables: los que la firman y los que no. Si alguien en PHP necesita drivers privativos para acceso a datos es mejor que estén fuera del núcleo de desarrollo.</p>
<p>Son muchos los desarrolladores que se niegan a pasar por el aro (la mayoría), asi que si las cosas no cambian y se llega a un acuerdo, probablemente se produzca un fork en PDO o directamente se quite del core, lo que sería una verdadera putada &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2008/01/26/el-culebron-pdo-v2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cómo firmar datos utilizando llaves PKCS#12 en PHP</title>
		<link>http://quarkblog.org/2008/01/21/como-firmar-datos-utilizando-llaves-pkcs12-en-php/</link>
		<comments>http://quarkblog.org/2008/01/21/como-firmar-datos-utilizando-llaves-pkcs12-en-php/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 14:10:17 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2008/01/21/como-firmar-datos-utilizando-llaves-pkcs12-en-php/</guid>
		<description><![CDATA[El formato de llavero PKCS#12 (extensiones .p12 y .pfx) es uno de los más populares para almacenar
claves criptográficas. En PHP podemos gestionar este tipo de claves a partir de la versión 5.2.2
gracias al módulo OpenSSL.
Como es muy nuevo y no hay documentación al respecto, dejo aquí un ejemplo de uso:



$file = &#34;/home/mmacia/my_secret_diary.txt&#34;;


$data = file_get_contents&#40;$file&#41;;


&#160;


$keywtore = [...]]]></description>
			<content:encoded><![CDATA[<p>El formato de llavero PKCS#12 (extensiones .p12 y .pfx) es uno de los más populares para almacenar<br />
claves criptográficas. En PHP podemos gestionar este tipo de claves a partir de la versión 5.2.2<br />
gracias al módulo OpenSSL.</p>
<p>Como es muy nuevo y no hay documentación al respecto, dejo aquí un ejemplo de uso:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="re0">$file</span> = <span class="st0">&quot;/home/mmacia/my_secret_diary.txt&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$data</span> = <a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="re0">$file</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$keywtore</span> = <span class="st0">&quot;/home/mmacia/cert.p12&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$passwd</span> = <span class="st0">&quot;fake_password&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// open PKCS#12 file</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> openssl_pkcs12_read<span class="br0">&#40;</span> <a href="http://www.php.net/file_get_contents"><span class="kw3">file_get_contents</span></a><span class="br0">&#40;</span><span class="re0">$keystore</span><span class="br0">&#41;</span>, <span class="re0">$certs</span>, <span class="re0">$passwd</span> <span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$signed</span> = <span class="kw2">null</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$pk</span> &nbsp; &nbsp; &nbsp;= <span class="re0">$certs</span><span class="br0">&#91;</span><span class="st0">&#8216;pkey&#8217;</span><span class="br0">&#93;</span>; <span class="co1">// get private key</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// sign data with private key</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <a href="http://www.php.net/openssl_sign"><span class="kw3">openssl_sign</span></a><span class="br0">&#40;</span><span class="re0">$data</span>, <span class="re0">$signature</span>, <span class="re0">$pk</span>, OPENSSL_ALGO_SHA1<span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$signature</span>= <a href="http://www.php.net/base64_encode"><span class="kw3">base64_encode</span></a><span class="br0">&#40;</span><span class="re0">$signature</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> Exception<span class="br0">&#40;</span><span class="st0">&#8216;Unexpected error signing file &quot;&#8217;</span> . <span class="re0">$file</span> . <span class="st0">&#8216;&quot;.&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">else</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; throw <span class="kw2">new</span> Exception<span class="br0">&#40;</span><span class="st0">&#8216;Cannot open the keystore &quot;&#8217;</span> . <span class="re0">$keystore</span> . <span class="st0">&#8216;&quot;&#8217;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><a href="http://www.php.net/print_r"><span class="kw3">print_r</span></a><span class="br0">&#40;</span><span class="re0">$signature</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2008/01/21/como-firmar-datos-utilizando-llaves-pkcs12-en-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>I hate PHP</title>
		<link>http://quarkblog.org/2007/11/29/i-hate-php/</link>
		<comments>http://quarkblog.org/2007/11/29/i-hate-php/#comments</comments>
		<pubDate>Thu, 29 Nov 2007 21:45:40 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[Internet]]></category>

		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/11/29/i-hate-php/</guid>
		<description><![CDATA[Un poquito de rant gracioso en formato twittero.
]]></description>
			<content:encoded><![CDATA[<p>Un <a href="http://ihatephp.net/">poquito de <em>rant</em> gracioso</a> en formato <em>twittero</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/11/29/i-hate-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Cómo usar autoload en varios componentes simultáneamente</title>
		<link>http://quarkblog.org/2007/11/14/como-usar-autoload-en-varios-componentes-simultaneamente/</link>
		<comments>http://quarkblog.org/2007/11/14/como-usar-autoload-en-varios-componentes-simultaneamente/#comments</comments>
		<pubDate>Wed, 14 Nov 2007 00:36:51 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/11/14/como-usar-autoload-en-varios-componentes-simultaneamente/</guid>
		<description><![CDATA[Autoload es uno de los llamados métodos mágicos de PHP que se dispara &#8220;mágicamente&#8221; cuando, al instanciar una clase, el interprete no es capaz de localizarla porque no se ha hecho el include/require del archivo correspondiente. Con autoload podemos sobrecargar esta funcionalidad y especificarle a PHP donde debe buscar sin tener que indicar explicita mente [...]]]></description>
			<content:encoded><![CDATA[<p>Autoload es uno de los llamados <a href="http://www.php.net/manual/en/language.oop5.autoload.php">métodos mágicos</a> de PHP que se dispara &#8220;mágicamente&#8221; cuando, al instanciar una clase, el interprete no es capaz de localizarla porque no se ha hecho el <code>include</code>/<code>require</code> del archivo correspondiente. Con <code>autoload</code> podemos sobrecargar esta funcionalidad y especificarle a PHP donde debe buscar sin tener que indicar explicita mente todos los archivos de clases de nuestro proyecto mediante <code>include</code>/<code>require</code>.</p>
<p>El problema viene cuando nuestro proyecto utiliza su propio <code>autoload</code> y un componente de un tercero utiliza otro <code>autoload</code> completamente diferente: sólo puede haber un punto para interceptar la llamada &#8220;autoload&#8221; e inevitablemente colisionan.</p>
<p>Afortunadamente la <a href="http://es2.php.net/manual/en/ref.spl.php">SPL</a> proporciona un mecanismo para apilar métodos <code>autoload</code>, tantos como sean necesarios, y evitar las colisiones. Veamos un ejemplo:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> Component1</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span> <span class="re0">$foo</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$foo</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> __autoload <span class="br0">&#40;</span> <span class="re0">$class_name</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !exist_class<span class="br0">&#40;</span><span class="re0">$class_name</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$f</span> = <a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> . <span class="st0">&#8216;/component1/lib/&#8217;</span> . <span class="re0">$class_name</span> . <span class="st0">&#8216;.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <a href="http://www.php.net/file_exists"><span class="kw3">file_exists</span></a><span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">require</span> <span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> Exception<span class="br0">&#40;</span><span class="st0">&#8216;Unnable to find class &#8216;</span> . <span class="re0">$class_name</span> . <span class="st0">&#8216;!&#8217;</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw2">class</span> Component2</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span> <span class="re0">$bar</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$bar</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> __autoload <span class="br0">&#40;</span> <span class="re0">$class_name</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !exist_class<span class="br0">&#40;</span><span class="re0">$class_name</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$f</span> = <a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> . <span class="st0">&#8216;/component2/lib/&#8217;</span> . <span class="re0">$class_name</span> . <span class="st0">&#8216;.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <a href="http://www.php.net/file_exists"><span class="kw3">file_exists</span></a><span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">require</span> <span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> Exception<span class="br0">&#40;</span><span class="st0">&#8216;Unnable to find class &#8216;</span> . <span class="re0">$class_name</span> . <span class="st0">&#8216;!&#8217;</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
</ol>
</div>
<p>Las clases <code>Component1</code> y <code>Component2</code> tienen dos funciones <code>__autoload()</code> diferentes.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">include</span> <span class="st0">&#8216;./Component1.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">include</span> <span class="st0">&#8216;./Component2.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$c1</span> = <span class="kw2">new</span> Component1_Lib<span class="br0">&#40;</span><span class="br0">&#41;</span>; <span class="co1">// error!!</span></div>
</li>
</ol>
</div>
<p>Los dos callbacks <code>autoload</code> colisionan.</p>
<p>Utizando <a href="http://es2.php.net/manual/en/ref.spl.php">SPL</a> podemos <strong>detectar si ya hay un callback autoload definido</strong> para sobreescribirlo, o apilar el nuestro. Además la función <code>autoload</code> puede meterse como metodo de una clase y mejorar un poco el aspecto del codigo:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">class</span> Component1</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> __construct<span class="br0">&#40;</span> <span class="re0">$foo</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <span class="re0">$foo</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; </div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw2">function</span> autoload<span class="br0">&#40;</span> <span class="re0">$class_name</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> !exist_class<span class="br0">&#40;</span><span class="re0">$class_name</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$f</span> = <a href="http://www.php.net/dirname"><span class="kw3">dirname</span></a><span class="br0">&#40;</span><span class="kw2">__FILE__</span><span class="br0">&#41;</span> . <span class="st0">&#8216;/component1/lib/&#8217;</span> . <span class="re0">$class_name</span> . <span class="st0">&#8216;.php&#8217;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <a href="http://www.php.net/file_exists"><span class="kw3">file_exists</span></a><span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">require</span> <span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw <span class="kw2">new</span> Exception<span class="br0">&#40;</span><span class="st0">&#8216;Unnable to find class &#8216;</span> . <span class="re0">$class_name</span> . <span class="st0">&#8216;!&#8217;</span>, <span class="nu0">0</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$callbacks</span> = spl_autoload_functions<span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// no autoload callbacks in stack</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">if</span> <span class="br0">&#40;</span> <span class="re0">$callbacks</span> === <span class="kw2">false</span> <span class="br0">&#41;</span></div>
</li>
<li class="li2">
<div class="de2"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; spl_autoload_register<span class="br0">&#40;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Component1&#8242;</span>, <span class="st0">&#8216;autoload&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">else</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="co1">// unregister existing callbacks</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span> <span class="re0">$callbacks</span> <span class="kw1">as</span> <span class="re0">$callback</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; spl_autoload_unregister<span class="br0">&#40;</span><span class="re0">$callback</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// register custom callback</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; spl_autoload_register<span class="br0">&#40;</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="st0">&#8216;Component1&#8242;</span>, <span class="st0">&#8216;autoload&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="co1">// re-register old ones</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="kw1">foreach</span> <span class="br0">&#40;</span> <span class="re0">$callbacks</span> <span class="kw1">as</span> <span class="re0">$callback</span> <span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; spl_autoload_register<span class="br0">&#40;</span><span class="re0">$callback</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>Cuidado porque la función <code>autoload</code> no es demasiado liviana y un uso abusivo puede provocar una bajada de rendimiento en el programa, pero de momento y hasta la versión 5.3, sin espacios de nombres en PHP no podemos hacer gran cosa <img src='http://quarkblog.org/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /></p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/11/14/como-usar-autoload-en-varios-componentes-simultaneamente/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automatizando la creación de paquetes Phar con Phing</title>
		<link>http://quarkblog.org/2007/11/14/automatizando-la-creacion-de-paquetes-phar-con-phing/</link>
		<comments>http://quarkblog.org/2007/11/14/automatizando-la-creacion-de-paquetes-phar-con-phing/#comments</comments>
		<pubDate>Tue, 13 Nov 2007 22:39:35 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/11/14/automatizando-la-creacion-de-paquetes-phar-con-phing/</guid>
		<description><![CDATA[Os dejo un task para Phing que programé para crear automáticamente paquetes Phar en PHP. Como no hay demasiada documentación sobre cómo extender Phing y crear nuevas tareas, os puede servir de guía para implementar las vuestras porque la verdad es que yo programé esta casi a ciegas.
La tarea: PHPArchiveTask
Y aquí el ejemplo de uso [...]]]></description>
			<content:encoded><![CDATA[<p>Os dejo un task para <a href="http://phing.info/trac/">Phing</a> que programé para crear automáticamente paquetes <a href="http://es2.php.net/phar">Phar</a> en PHP. Como no hay demasiada documentación sobre cómo extender Phing y crear nuevas tareas, os puede servir de guía para implementar las vuestras porque la verdad es que yo programé esta casi a ciegas.</p>
<p>La tarea: <a href='http://quarkblog.org/wp-content/uploads/2007/11/phparchivetask.txt' title='php archive task for phing'>PHPArchiveTask</a></p>
<p>Y aquí el ejemplo de uso del XML del <code>build.xml</code> correspondiente:</p>
<pre>
<span style="font-weight: bold;color: #000000;">&lt;project</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;builder&#8221;</span><span style="color: #008000;"> default=</span><span style="color: #aa0000;">&#8220;package&#8221;</span><span style="font-weight: bold;color: #000000;">&gt;</span>
<span style="color: #000000;">	</span><span style="font-style: italic;color: #808080;">&lt;!&#8211; custom tasks &#8211;&gt;</span>
<span style="color: #000000;">	</span><span style="font-weight: bold;color: #000000;">&lt;taskdef</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;phar&#8221;</span><span style="color: #008000;"> classname=</span><span style="color: #aa0000;">&#8220;phing.task.PHPArchiveTask&#8221;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">/&gt;</span>
<span style="color: #000000;">	</span>
<span style="color: #000000;">	</span><span style="font-style: italic;color: #808080;">&lt;!&#8211; custom properties &#8211;&gt;</span>
<span style="color: #000000;">	</span><span style="font-weight: bold;color: #000000;">&lt;property</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;phar.version&#8221;</span><span style="color: #008000;"> value=</span><span style="color: #aa0000;">&#8220;1&#8243;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">/&gt;</span>
<span style="color: #000000;">	</span><span style="font-weight: bold;color: #000000;">&lt;property</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;dist.dir&#8221;</span><span style="color: #008000;"> value=</span><span style="color: #aa0000;">&#8220;./dist&#8221;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">/&gt;</span>
<span style="color: #000000;">	</span><span style="font-weight: bold;color: #000000;">&lt;property</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;src.dir&#8221;</span><span style="color: #008000;"> value=</span><span style="color: #aa0000;">&#8220;./src&#8221;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">/&gt;</span>
<span style="color: #000000;">	</span>
<span style="color: #000000;">	</span>
<span style="color: #000000;">	</span><span style="font-weight: bold;color: #000000;">&lt;target</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;package&#8221;</span><span style="font-weight: bold;color: #000000;">&gt;</span>
<span style="color: #000000;">		</span><span style="font-weight: bold;color: #000000;">&lt;echo</span><span style="color: #008000;"> msg=</span><span style="color: #aa0000;">&#8220;Building package &#8230;&#8221;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">/&gt;</span>
<span style="color: #000000;">		</span><span style="font-weight: bold;color: #000000;">&lt;phar</span>
<span style="color: #008000;">			version=</span><span style="color: #aa0000;">&#8220;${phar.version}&#8221;</span><span style="color: #000000;"> </span>
<span style="color: #008000;">			bootstrap=</span><span style="color: #aa0000;">&#8220;lib/phar-bootstrap.php&#8221;</span><span style="color: #000000;"> </span>
<span style="color: #008000;">			gzip=</span><span style="color: #aa0000;">&#8220;true&#8221;</span><span style="color: #000000;"> </span>
<span style="color: #008000;">			output=</span><span style="color: #aa0000;">&#8220;{dist.dir}/packages/myFirstPharPackage${phar.version}.phar&#8221;</span><span style="color: #000000;"> </span>
<span style="color: #008000;">			stub=</span><span style="color: #aa0000;">&#8220;{src.dir}/phar-stub.php&#8221;</span><span style="font-weight: bold;color: #000000;">&gt;</span>
<span style="color: #000000;">	</span>
<span style="color: #000000;">			</span><span style="font-weight: bold;color: #000000;">&lt;fileset</span><span style="color: #008000;"> dir=</span><span style="color: #aa0000;">&#8220;{src.dir}&#8221;</span><span style="font-weight: bold;color: #000000;">&gt;</span>
<span style="color: #000000;">				</span><span style="font-weight: bold;color: #000000;">&lt;include</span><span style="color: #008000;"> name=</span><span style="color: #aa0000;">&#8220;classes/**/*.php&#8221;</span><span style="color: #000000;"> </span><span style="font-weight: bold;color: #000000;">/&gt;</span>
<span style="color: #000000;">			</span><span style="font-weight: bold;color: #000000;">&lt;/fileset&gt;</span>
<span style="color: #000000;">		</span><span style="font-weight: bold;color: #000000;">&lt;/phar&gt;</span>
<span style="color: #000000;">	</span><span style="font-weight: bold;color: #000000;">&lt;/target&gt;</span>

<span style="font-weight: bold;color: #000000;">&lt;/project&gt;</span></pre>
<p>Deberéis colocar la tarea en la ruta <code>phing/task/PHPArchiveTask.php</code> a partir del lugar donde esté el <code>build.xml</code>, tal y como indica el espacio de nombres (de esos espacios de nombres de mentira que hay en PHP&#8230;). El resto de opciones creo que están bastante claras.</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/11/14/automatizando-la-creacion-de-paquetes-phar-con-phing/feed/</wfw:commentRss>
		</item>
		<item>
		<title>60 optimizaciones para tus programas PHP</title>
		<link>http://quarkblog.org/2007/10/16/60-optimizaciones-para-tus-programas-php/</link>
		<comments>http://quarkblog.org/2007/10/16/60-optimizaciones-para-tus-programas-php/#comments</comments>
		<pubDate>Mon, 15 Oct 2007 22:47:13 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/10/16/60-optimizaciones-para-tus-programas-php/</guid>
		<description><![CDATA[
Si un método puede ser static, decláralo estático. La velocidad se incrementa en un factor de 4.
echo es más rápido que print, aunque la diferencia es despreciable.
Inicializa el contador de tus bucles for antes y no en el propio bucle.
Si tienes que iterar un objeto o un array, utiliza SPL en lugar de bucles recursivos.
Destruye [...]]]></description>
			<content:encoded><![CDATA[<ol>
<li>Si un método puede ser <code>static</code>, decláralo estático. La velocidad se incrementa en un factor de 4.</li>
<li><code>echo</code> es más rápido que <code>print</code>, aunque la diferencia es despreciable.</li>
<li>Inicializa el contador de tus bucles <code>for</code> antes y no en el propio bucle.</li>
<li>Si tienes que iterar un objeto o un array, utiliza SPL en lugar de bucles recursivos.</li>
<li>Destruye las variables que ya no utilices con <code>unset()</code> para liberar memoria, especialmente si son objetos o arrays pesados. Si utilizas OOP, revisa el destructor <code>__destruct()</code> en este sentido.</li>
<li>Si tienes que recorrer un array enorme y no te interesa guardarlo, considera utilizar <code>array_shift()</code> para ir leyendo y borrando a la vez.</li>
<li>No abuses de <code>__get()</code>, <code>__set()</code> y <code>__autoload()</code>.</li>
<li><code>require_once()</code> es pesado. Muy pesado en PHP &lt; 5.0.</li>
<li>Utiliza paths absolutos a los ficheros en los <code>include()</code> y <code>require()</code>, el SO tarda menos en resolver las rutas al fichero.</li>
<li>Si necesitas saber el <em>timestamp</em> de acceso a un script, considera utilizar <code>$_SERVER['REQUEST_TIME']</code> en lugar de <code>time()</code> </li>
<li>Comprueba si puedes usar <code>strncasecmp()</code>, <code>strpbrk()</code> y <code>stripos()</code> en lugar de expresiones regulares.</li>
<li><code>str_replace()</code> es más rápido que <code>preg_replace()</code>, pero <code>strtr()</code> es hasta 4 veces más rápido que <code>str_replace()</code>.</li>
<li>Si la función, como la función de reemplazo de cadenas, acepta dos arrays y un carácter como argumentos, y tu lista de argumentos no es muy larga, considera escribir varias sentencias de reemplazo redundantes, pasando un carácter cada vez, en lugar de una linea de código que acepte arrays como búsqueda y reemplazo.</li>
<li>La supresión de errores con <code>@</code> es bastante ineficiente a la par que desaconsejable.</li>
<li><code>eval()</code> is evil (y además horrorosamente lento).</li>
<li><code>$row['id']</code> es hasta 7 veces más rápido que <code>$row[id]</code></li>
<li>Si una variable de clase es constante, utiliza <code>const</code>.</li>
<li>Los mensajes de error son ineficientes, utilizalos sólo cuando sea necesario.</li>
<li>No uses funciones dentro de los bucles, como <code>for ($x=0; $x &lt; count($array); $x++)</code>. La función <code>count()</code> se ejecuta cada vez que se repita el bucle.</li>
<li>Incrementar una variable local en un método es lo más rápido. Casi lo mismo que llamar a una variable local en una función.</li>
<li>Incrementar una variable global es dos veces más lento que hacerlo con una variable local.</li>
<li>Incrementar una propiedad de un objeto (por ejemplo <code>$this->prop++</code>) es 3 veces más lento que hacerlo sobre una variable local.</li>
<li>Incrementar una variable indefinida es hasta 10 veces más lento que hacerlo en una ya inicializada.</li>
<li>Declarar una variable global sin utilizarla también enlentece la ejecución. PHP comprueba si existe.</li>
<li>La cantidad de métodos definidos en una clase no afecta al rendimiento.</li>
<li>Los métodos de la clase concreta se ejecutan más rápidos que los de la clase base.</li>
<li><code>$localvar++</code> es hasta 15 veces más rápido que <code>function inc(){ $localvar++; }</code>.</li>
<li>Las cadenas encerradas entre comillas simples son más rápidas que las que lo están con comillas dobles porque PHP no expande las variables que puedan contener. Si usas PHP 5+, la diferencia es mínima.</li>
<li>Cuando se aplica <code>echo</code> a una lista de cadenas por argumento, es más rápido separarlas con una coma (,) en lugar del operador de concatenación (.). Esto sólo funciona con <code>echo</code> por ser una construcción del lenguaje y no una función.</li>
<li>Un script PHP es servido por Apache entre 2 y 10 veces más lento que una página estática. Cachea resultados cuando sea posible.</li>
<li>Los scripts PHP se &#8220;compilan&#8221; cada vez que son ejecutados a menos que se guarde el código objeto en un cache. Las diferentes herramientas de compilación de PHP incrementan el rendimiento hasta un 100%.</li>
<li>Puestos a cachear, Memcached es mucho más rápido y versátil que un cache a disco. APC también da buen resultado pero es menos escalable.</li>
<li>Usa <code>ip2long()</code> y <code>long2ip()</code> para almacenar direcciones IP como números en lugar de como cadenas. Reduce el espaco en un factor de 4 y los cálculos de rango, máscara y ordenaciones son más sencillos y rápidos.</li>
<li>Usa la extensión SOAP nativa en lugar de NuSOAP.</li>
<li>Valida las direcciones de correo electrónico con <code>checkdnsrr()</code>.</li>
<li><code>php_filter()</code> mejor y más rápido que tu sistema <em>home made</em> de validación.</li>
<li>Las funciones <code>mysql_*</code> son más lentas que <code>mysqli_*</code>, pero no tan eficientes como el driver <code>mysqlnd</code> para PDO (disponible en el inminente PHP 5.3)</li>
<li>Usa sentencias preparadas, en lugar de concatenar las consultas a mano, para mejorar el rendimiento y frenar significativamente las SQL-Injections. ( y <a href="http://en.wikipedia.org/wiki/Matt_Mullenweg">Matt</a> puede decir misa, hacedme caso a mi )</li>
<li>No reinventes la rueda, mira a ver si puedes aprovechar algo de PEAR, PECL, SourceForge, CakePHP, CodeIgniter, Zend Framework, &#8230;</li>
<li>Utiliza <code>highlight_file()</code> para postear código formateado y bonito en los foros (por favor!!).</li>
<li>Si guardas un objeto o array serializado en la base de datos, considera usar <code>gzcompress()</code> y  <code>gzuncompress()</code> para ahorrar espacio. GZip puede reducir el tamaño de un texto plano hasta en un 90%.</li>
<li>El operador ternario no es más rápido que un <code>if-else</code>.</li>
<li><code>empty()</code> es más rápido que <code>$var == ''</code>, pero es más rápido el operador identidad <code>$var === ''</code>. En general la identidad es más rápida en cualquier situación.</li>
<li><code>do-while</code> es más rápido que <code>while</code>, pero más lento que <code>for</code>. Lo primero a optimizar de un programa son los bucles ( un viejo truco de Algoritmia y Arquitectura de computadores <img src='http://quarkblog.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> )</li>
<li>Si necesitas determinar si una cadena tiene un cierto tamaño, es más rápido utilizar la construcción del lenguaje <code>!isset($str{5})</code> que la función <code>strlen($str) &lt; 5</code></li>
<li>el preincremento <code>++$i</code> es más rápido que el postincremento <code>$i++</code> debido a interioridades del interprete de Zend, de echo es una de las optimizaciones a nivel de OPCODE más utilizadas por los compiladores de PHP.</li>
<li>Usa <code>preg_*</code> en lugar de <code>ereg_*</code>, está a punto de desaparecer y es mucho más lento.</li>
<li>Usa direcciones IP en lugar de nombres de dominio.</li>
<li>El manejador de flujos <code>ob_start()</code> puede aumentar el rendimiento hasta en un 25%.</li>
<li>El paso de argumentos por referencia en PHP no es igual al paso de una referencia en C mediante un puntero. En PHP una referencia sirve para acceder a una variable mediante dos nombres distintos (nombre de variable y valor de la variable son cosas distintas en PHP). Por tanto pasar arrays por referencia como en C, en realidad, es más lento que hacerlo por valor. En PHP 5+ los objetos se pasan explícitamente por referencia.</li>
<li>Un uso apropiado de las referencias como alias de nombre de variable:
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$a</span><span class="br0">&#91;</span><span class="st0">&#8216;b&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;c&#8217;</span><span class="br0">&#93;</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// 2 accesos por iteración a la tabla hash </span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// donde PHP almacena las variables</span></div>
</li>
<li class="li2">
<div class="de2"><span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span> = <span class="nu0">0</span>; <span class="re0">$i</span> &lt; <span class="nu0">5</span>; <span class="re0">$i</span>++<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$a</span><span class="br0">&#91;</span><span class="st0">&#8216;b&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;c&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> = <span class="re0">$i</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">// con un alias por referencia es mas rápido</span></div>
</li>
<li class="li2">
<div class="de2"><span class="re0">$ref</span> =&amp; <span class="re0">$a</span><span class="br0">&#91;</span><span class="st0">&#8216;b&#8217;</span><span class="br0">&#93;</span><span class="br0">&#91;</span><span class="st0">&#8216;c&#8217;</span><span class="br0">&#93;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span> = <span class="nu0">0</span>; <span class="re0">$i</span> &lt; <span class="nu0">5</span>; <span class="re0">$i</span>++<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$ref</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span> = <span class="re0">$i</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
</pre>
</li>
<li>La manera más rápida a este lado de Rio Grande para detectar si el SO es Unix o no es utilizar la constante <code>DIRECTORY_SEPARATOR</code>.</li>
<li>La manera más rápida de concatenar muchas cadenas de poco tamaño es abrir un flujo de salida con <code>ob_start()</code> y hacer un <code>echo</code> de todas ellas para despues recoger la cedena final con <code>ob_get_contents()</code>. Esto es así porque en el tratamiento de cadenas el factor limitante es la reserva de memoria y al crear un flujo se reservan de golpe 40K, aumentando en pedazos de 10K cuando hace falta más.</li>
<li>En las sentencias <code>switch()</code> ordena los casos empezando por los más frecuentes.</li>
<li>Procesar ficheros XML con expresiones regulares es más rápido que hacerlo con SAX o DOM. Atención: el uso de expresiones regulares para procesar XMl puede acortar significativamente su esperanza de vida.</li>
<li>Eliminar los comentarios o escribir en una sola linea no hace que se ejecute más rápido, lo único que consigues es que los demás te odien a muerte.</li>
<li>Usar objetos no hace que todo sea más rápido, más bien al contrario, pero utilizarlos mejora otras muchas cosas.</li>
<li>Cuanto menos (x)HTML en la salida del script, más rápido renderiza la pagina.</li>
<li>Utiliza constantes en lugar de funciones: <code>PHP_VERSION</code> vs. <code>php_version()</code>, <code>PHP_OS</code> vs. <code>php_uname()</code>, <code>PHP_SAPI</code> vs. <code>php_sapi_name()</code>, etc.</li>
<li>Si todo lo demás falla &#8230; escribe una extensión en C.</li>
</ol>
<p>Conclusión: no prestes mucha atención a todo esto; dependiendo de la carga y la máquina, algunas optimizaciones apenas van a ser apreciables por el usuario final. Sólo con cambiar los <code>while</code> por <code>do-while</code> no va a hacer que tu programa corra como el viento, cuanto mejor conozcas tu stack de software y los entresijos de la aplicación más profundas serán las mejoras que puedas aplicar.</p>
<p>¿Alguien conoce alguna más?</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/10/16/60-optimizaciones-para-tus-programas-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>PHP Archive (Phar)</title>
		<link>http://quarkblog.org/2007/09/05/php-archive-phar/</link>
		<comments>http://quarkblog.org/2007/09/05/php-archive-phar/#comments</comments>
		<pubDate>Tue, 04 Sep 2007 22:21:32 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/09/05/php-archive-phar/</guid>
		<description><![CDATA[PHP Archive es una extensión que permite desplegar aplicaciones PHP autocontenidas en un único archivo, con extensión .phar obviamente. 
Esta extensión todavía no forma parte de la distribución oficial (pero esto cambiará en PHP6, sino antes) así que para instalarla hay que compilarla o utilizar PEAR/PECL, pero he encontrado problemas para hacerlo con los paquetes [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://es.php.net/manual/en/ref.phar.php">PHP Archive</a> es una extensión que permite desplegar aplicaciones PHP autocontenidas en un único archivo, con extensión <em>.phar</em> obviamente. </p>
<p>Esta extensión todavía no forma parte de la distribución oficial (pero esto cambiará en PHP6, sino <a href="http://devzone.zend.com/article/2058-Zend-Weekly-Summaries-Issue-339#Heading6">antes</a>) así que para instalarla hay que compilarla o utilizar <a href="http://pecl.php.net">PEAR/PECL</a>, pero he encontrado problemas para hacerlo con los paquetes de Ubuntu/Debian y me consta que en otras distros ocurre lo mismo. ¿Solución? Compilar todo el stack de PHP a mano para después compilar la extensión.</p>
<p>Como esto es un coñazo he decidido publicar la extensión compilada y lista para utilizar (si os fiáis de mí claro):</p>
<div class="center"><strong><a href="http://quarkblog.org/wp-content/uploads/2007/09/phar-1.2.1.tar.gz">Phar 1.2.1</a></strong></div>
<p>MD5: f4e82469c7a4d98df5daa30b02b35db4</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/09/05/php-archive-phar/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Nuevas métricas en PHPUnit</title>
		<link>http://quarkblog.org/2007/08/27/nuevas-metricas-en-phpunit/</link>
		<comments>http://quarkblog.org/2007/08/27/nuevas-metricas-en-phpunit/#comments</comments>
		<pubDate>Mon, 27 Aug 2007 20:05:43 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/08/27/nuevas-metricas-en-phpunit/</guid>
		<description><![CDATA[Mientras el blog ardía &#8230;
La semana pasada entró en el repositorio de PHPUnit una nueva métrica de software que sirve para detectar el índice de código duplicado de un proyecto (el típico copy&#038;paste), así que poco a poco PHPUnit deja de ser una herramienta &#8220;sólo para tests unitarios&#8221;.
Esta nueva métrica se une al extenso abanico [...]]]></description>
			<content:encoded><![CDATA[<p><em>Mientras el blog ardía</em> &#8230;</p>
<p>La semana pasada entró en el repositorio de <a href="http://www.phpunit.de/">PHPUnit</a> una nueva métrica de software que sirve para detectar el <strong>índice de código duplicado</strong> de un proyecto (el típico <em>copy&#038;paste</em>), así que poco a poco PHPUnit deja de ser una herramienta &#8220;sólo para tests unitarios&#8221;.</p>
<p>Esta nueva métrica se une al <a href="http://sebastian-bergmann.de/archives/689-PHPUnit-and-Software-Metrics.html">extenso abanico</a> de las ya existentes y pueden utilizarse a modo informativo o como restricciones a la hora de programar. Para ello, PHPUnit es capaz de integrarse con otra herramienta bien conocida en el mundo Java <img src='http://quarkblog.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , <a href="http://cruisecontrol.sourceforge.net/">CruiseControl</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/08/27/nuevas-metricas-en-phpunit/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Quality Assurance en PHP</title>
		<link>http://quarkblog.org/2007/08/17/quality-assurance-en-php/</link>
		<comments>http://quarkblog.org/2007/08/17/quality-assurance-en-php/#comments</comments>
		<pubDate>Fri, 17 Aug 2007 19:18:47 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/08/17/quality-assurance-en-php/</guid>
		<description><![CDATA[Algunos apuntes rápidos sobre tecnologías que hacen que este verano esté trabajando en lugar de estar tumbado bajo una palmera sorbiendo licor de un coco con sombrilla:
Xdebug
Un depurador, perfilador y analizador de trazas para PHP con posibilidad de realizar code coverage (no me atrevo a traducirlo  
Lo mejor de esta herramienta son los volcados [...]]]></description>
			<content:encoded><![CDATA[<p>Algunos apuntes rápidos sobre tecnologías que hacen que este verano esté trabajando en lugar de estar tumbado bajo una palmera sorbiendo licor de un coco con sombrilla:</p>
<h4><a href="http://xdebug.org/">Xdebug</a></h4>
<p>Un <strong>depurador</strong>, <strong>perfilador</strong> y <strong>analizador de trazas</strong> para PHP con posibilidad de realizar <strong>code coverage</strong> (no me atrevo a traducirlo <img src='http://quarkblog.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Lo mejor de esta herramienta son los <strong>volcados de pila</strong> y <strong>variables en memoria</strong>, una auténtica gozada después de sufrir durante años los <code>echo</code>, los <code>var_dump</code> y los <code>printr</code>.</p>
<p>El tema del <a href="http://xdebug.org/docs/profiler">perfilado de código</a> también es bastante interesante de cara a ver dónde se pierden ciclos en los scripts. En Linux se puede ver el árbol de llamadas del código con el <a href="http://kcachegrind.sourceforge.net/cgi-bin/show.cgi">KCacheGrind</a> de toda la vida (viene con KDE-devel en todas las distros); para los que sufren Windows está el port <a href="http://sourceforge.net/projects/wincachegrind">WinCacheGrind</a>, pero ya aviso que es lento y pesado a más no poder. Para OSX ni idea, imagino que habrá un port de KCacheGrind o como mínimo se podrá utilizar la instrumentación de <code>valgrind</code>/<code>callgrind</code> a pelo, no se.</p>
<p>También se puede <a href="http://blog.lucke.info/2007/08/03/debugging-php-with-free-tools-pdt-xdebug2/">integrar</a> con <a href="http://www.eclipse.org/">Eclipse</a> + <a href="http://www.eclipse.org/pdt/">PDT</a> para depurar sin salir del IDE, aunque es un poco patatero todavía.</p>
<p>Para instalar Xdebug lo mejor es tirar de los repositorios <a href="http://pear.php.net/">PEAR/PECL</a> y compilarlo. No hay paquetes para Ubuntu ni para Debian de momento.</p>
<h4><a href="http://www.phpunit.de">PHPUnit</a></h4>
<p>Un framework para realizar <strong>tests unitarios</strong> de manera tan sencilla que da reparo no hacerlos <img src='http://quarkblog.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Antes utilizaba <a href="http://simpletest.org/">SimpleTest</a> pero este me gusta mucho más por la versatilidad que ofrece y el rápido desarrollo. Está completamente orientado a objetos y puede funcionar conjuntamente con Xdebug para realizar unos bonitos informes de cobertura.</p>
<p>PHPUnit es una herramienta sobre la que se está trabajando muy activamente. Entre las cosas interesantes que se pueden hacer (a parte de lo que he dicho) quizá destacaría el <a href="http://www.phpunit.de/wiki/GSoC2007MutationTesting">mutation testing</a> y el test para bases de datos <a href="http://www.ds-o.com/archives/62-PHPDBUnit-Testing-DB-interaction-with-PHPUnit.html">PHPDBUnit</a> que es un port directo del DBUnit de Java.</p>
<p>Estas funcionalidades no están publicadas actualmente pero los ansiosos pueden hacer un checkout del svn de PHPUnit para empezar a hackear, están en <code>/phpunit/branches/mutation_testing</code> y <code>/phpunit/branches/dbunit</code> respectivamente.</p>
<p>Otra herramienta increíble que puede interactuar con PHPUnit es <a href="http://www.openqa.org/selenium/">Selenium</a> del que ya hablé por aquí hace un tiempo. Con estas dos joyitas se puede construir un <a href="http://devzone.zend.com/article/2242-Acceptance-Testing-of-Web-Applications-with-PHP">sistema de tests de aceptación</a> completo para aplicaciones web.</p>
<p>Para instalar PHPUnit, lo mejor de nuevo, es tirar de Pear porque la versión que viene empaquetada en Debian/Ubuntu es bastante antigua.</p>
<h4><a href="http://phing.info/trac/">Phing</a></h4>
<p>¿Habeis utilizado alguna vez <a href="http://ant.apache.org/">Apache Ant</a> en Java? pues Phing es lo mismito pero para PHP; guarda una cierta compatibilidad con la sintáxis de Ant pero incorporando algunos <code>targets</code> útiles para PHP,como por ejemplo la integración con PHPUnit <img src='http://quarkblog.org/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> o el acceso a Subversion.</p>
<p>Tampoco es que me guste mucho utilizar XML para hacer los scripts de los despliegues &#8230; porque el XML tiende a hacer las cosas complicadas imposibles, pero para las tareas habituales no se requieren más de una docena de lineas.</p>
<p>Para instalarlo, más Pear.</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/08/17/quality-assurance-en-php/feed/</wfw:commentRss>
		</item>
		<item>
		<title>SVN Hook: asociar acciones a keywords de Trac</title>
		<link>http://quarkblog.org/2007/05/02/svn-hook-asociar-acciones-a-keywords-de-trac/</link>
		<comments>http://quarkblog.org/2007/05/02/svn-hook-asociar-acciones-a-keywords-de-trac/#comments</comments>
		<pubDate>Wed, 02 May 2007 21:20:11 +0000</pubDate>
		<dc:creator>Moisés Maciá</dc:creator>
		
		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Programación]]></category>

		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://quarkblog.org/2007/05/02/svn-hook-asociar-acciones-a-keywords-de-trac/</guid>
		<description><![CDATA[En Trac, a la hora de introducir un nuevo ticket, le podemos asignar keywords:

Este es un campo sin valor aparente mas que para taggear tickets hasta que el otro día se me ocurrió un hack curioso: utilizar los keywords asociados a un ticket para disparar acciones como por ejemplo notificaciones por email, reconstruir la documentación, [...]]]></description>
			<content:encoded><![CDATA[<p>En <a href="http://trac.edgewall.org/">Trac</a>, a la hora de introducir un nuevo ticket, le podemos asignar keywords:</p>
<div class="center"><img src='http://quarkblog.org/wp-content/uploads/2007/05/trac-keywords.png' alt='Trac Keywords' /></div>
<p>Este es un campo sin valor aparente mas que para <em>taggear</em> tickets hasta que el otro día se me ocurrió un hack curioso: <strong>utilizar los keywords asociados a un ticket para disparar acciones</strong> como por ejemplo <strong>notificaciones por email</strong>, <strong>reconstruir la documentación</strong>, etc.</p>
<h4>Cómo funciona</h4>
<p>Funciona de forma similar al anterior hook que comenté, el <a href="http://quarkblog.org/2007/03/20/svn-hook-como-gestionar-tickets-automaticamente-en-trac/">auto cierre de tickets</a>: responde a mensajes del estilo <em>&#8220;changed blah blah to do this or that, fixes #34&#8243;</em>. </p>
<p>Si el mensaje contiene alguna orden de cierre sobre un ticket (las ordenes son personalizables a través del array <code>$msgClose</code>), se pasa a ver si el ticket tiene keywords (puede tener varias separadas por comas). </p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$msgClose</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;close&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;closed&#8217;</span>,</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="st0">&#8216;closes&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;fix&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;fixed&#8217;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;fixes&#8217;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>En este caso se ejecutan las acciones pertinentes.</p>
<p>Para añadir nuevas acciones hay que mapearlas en el array <code>$keyword2action</code>.</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re0">$keyword2action</span> = <a href="http://www.php.net/array"><span class="kw3">array</span></a> <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="st0">&#8216;publish&#8217;</span>&nbsp; &nbsp;&nbsp; &nbsp; =&gt; <span class="st0">&#8216;emailThis&#8217;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<p>En el ejemplo vemos que la keyword <code>publish</code> ejecuta la acción <code>emailThis</code>.</p>
<p>Por último los callbacks de las acciones tienen esta pinta:</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw2">function</span> action_emailThis <span class="br0">&#40;</span><span class="re0">$commit</span>=<span class="st0">&#8221;</span>, <span class="re0">$description</span>=<span class="st0">&#8221;</span>, <span class="re0">$url</span>=<span class="st0">&#8221;</span>, <span class="re0">$ticket</span>=<span class="nu0">0</span><span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#123;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$to</span> = <span class="st0">&quot;mailing@domain.com&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$subject</span> = <span class="st0">&quot;[My Awesome Project] Cheers!, we have closed ticket #$ticket&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> = <span class="st0">&quot;Ticket description:<span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="st0">&quot;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="re0">$description</span> . <span class="st0">&quot;<span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="st0">&quot;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<span class="es0">\r</span><span class="es0">\n</span><span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="st0">&quot;Commit message:<span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="st0">&quot;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="re0">$commit</span> . <span class="st0">&quot;<span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="st0">&quot;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<span class="es0">\r</span><span class="es0">\n</span><span class="es0">\r</span><span class="es0">\n</span>&quot;</span>;</div>
</li>
<li class="li2">
<div class="de2">&nbsp; &nbsp; <span class="re0">$msg</span> .= <span class="st0">&quot;More info in $url&quot;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; <a href="http://www.php.net/mail"><span class="kw3">mail</span></a> <span class="br0">&#40;</span><span class="re0">$to</span>, <span class="re0">$subject</span>, <span class="re0">$msg</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#125;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
</ol>
</div>
<p>Donde <code>$commit</code> es el mensaje de cierre del ticket, <code>$description</code> es la descripción del ticket en Trac, <code>$url</code> es la URL al ticket completo y su historial en Trac y por último <code>$ticket</code> es el número de identificación del ticket.</p>
<h4>Qué necesito</h4>
<ol>
<li>Una máquina con Trac, Subversion y un servidor de correo correctamente configurados.</li>
<li>¡<a href="http://quarkblog.org/wp-content/uploads/2007/05/trac-keywords2action.txt">El script</a>!</li>
</ol>
<p>En el gancho <code>post-commit</code> de Subversion hay que colocar las siguientes variables (si no están ya):</p>
<div class="dean_ch" style="white-space: wrap;">
<ol>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="re2">REPOS=</span><span class="st0">&quot;$1&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">REV=</span><span class="st0">&quot;$2&quot;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="re2">LOG=</span>`/usr/bin/svnlook log -r <span class="re1">$REV</span> <span class="re1">$REPOS</span>`</div>
</li>
<li class="li2">
<div class="de2"><span class="re2">TRAC_ENV=</span><span class="st0">&#8216;/somewhere/trac/project/&#8217;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">/usr/bin/php -q trac-keyword2action.php &#8211;trac-path <span class="st0">&quot;$TRAC_ENV&quot;</span> \</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8211;message <span class="st0">&quot;$LOG&quot;</span> \</div>
</li>
<li class="li1">
<div class="de1">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&#8211;trac-url <span class="st0">&quot;http://trac.mydomain.com/&quot;</span></div>
</li>
<li class="li2">
<div class="de2">&nbsp;</div>
</li>
</ol>
</div>
<h4>Problemas</h4>
<ul>
<li>Trac debe utilizar SQLite como backend, aunque es posible utilizar MySQL modificando un par de lineas del código.</li>
<li>PHP5 + <a href="http://es2.php.net/manual/es/ref.pdo.php">PDO</a> + SQLite, no suele estar instalado en servidores <q>baratos</q>.</li>
<li>Si se cierra un ticket sin pasar por Subversion no funciona.</li>
</ul>
<h4>Usos</h4>
<p>Hay algunos cambios mayores en un proyecto que por alguna razón nos interesa comunicar a los cuatro vientos cuando finalmente son implementados, bien a una lista de correo, un canal RSS, un informe para el jefe, etc. Estos tickets especiales pueden marcarse para desencadenar la acción elegida.</p>
<p>También es útil cuando se reporta un <em>typo</em> en la documentación o en los archivos de cadenas para localizar/internacionalizar. Marcando estos tickets se puede regenerar de nuevo los archivos de documentación o compilar las traducciones tan pronto como el fallo este resuelto.</p>
<p>¿Alguna sugerencia más? ¿Para qué lo emplearíais?</p>
]]></content:encoded>
			<wfw:commentRss>http://quarkblog.org/2007/05/02/svn-hook-asociar-acciones-a-keywords-de-trac/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 11.890 seconds -->
<!-- Cached page served by WP-Cache -->
