<?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>Calcifer &#187; php</title>
	<atom:link href="http://blog.calcifer.com.ar/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.calcifer.com.ar</link>
	<description></description>
	<lastBuildDate>Sat, 02 Oct 2010 05:32:38 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>GNU gettext con php5</title>
		<link>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/</link>
		<comments>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/#comments</comments>
		<pubDate>Sat, 21 Mar 2009 17:55:06 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[gnu/linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=226</guid>
		<description><![CDATA[
GNU gettext es la biblioteca GNU de internacionalización (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.
wikipedia
La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://blog.calcifer.com.ar/uploads/2009/03/gnu-head-sm.jpg" alt="gnu-head-sm" title="gnu-head-sm" width="129" height="122" class="alignright size-full wp-image-231" /></p>
<p><a href="http://www.gnu.org/software/gettext/gettext.html" class="wikipedia">GNU gettext</a> es la biblioteca <a href="http://es.wikipedia.org/wiki/GNU" class="wikipedia">GNU</a> de <a href="http://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_(computaci%C3%B3n)" class="wikipedia">internacionalización</a> (i18n) y es usada para escribir programas con interfaz en múltiples idiomas.</p>
<p><a href="http://es.wikipedia.org/wiki/Internacionalizaci%C3%B3n_(computaci%C3%B3n)" class="wikipedia">wikipedia</a></p>
<blockquote title="wikipedia.org"><p>La internacionalización es el proceso de diseñar software de manera tal que pueda adaptarse a diferentes idiomas y regiones sin necesidad de cambios de ingeniería ni de código. La localización es el proceso de adaptar el software para una región específica mediante la adición de componentes específicos de un locale y la traducción de los textos, por lo que también se le puede denominar regionalización.<br />
&#8230;<br />
Es una práctica común en el idioma inglés (sobre todo en el ámbito de la computación), abreviar internationalization como &#8220;i18n&#8221;. Ello se debe a que entre la primera i y la última n de dicha palabra hay 18 letras. Lo mismo sucede con localization, que se abrevia &#8220;L10n&#8221;.
</p></blockquote>
<h3>gettext en PHP</h3>
<p>Existen dos formas de usar gettext en PHP: mediante la <a href="http://ar2.php.net/manual/en/book.gettext.php" class="external">extensión gettext nativa de PHP</a> o utilizando la librería <a href="http://savannah.nongnu.org/projects/php-gettext/" class="external">PHP-gettext</a>, escrita en PHP, que no necesita ninguna extensión.</p>
<p>La forma de usar gettext es</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"># @file: index.php<br />
<span class="kw2">&lt;?php</span><br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/_"><span class="kw3">_</span></a><span class="br0">&#40;</span><span class="st0">&quot;hello world&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div></td></tr></tbody></table></div>
<p>La función<code>_()</code>, alias de<code>gettext()</code>, devolverá la cadena &#8220;hello world&#8221; en el lenguaje correspondiente, de acuerdo al <a href="http://en.wikipedia.org/wiki/Locale" class="wikipedia">locale</a> que hayamos seleccionado.</p>
<p>Si ejecutamos el script obtendremos &#8220;hello world&#8221; como salida, puesto que no hemos indicado ningún locale, ni creado ningún catálogo de traducción. Necesitamos crear el archivo<code>comments.po</code>con la traducción de la cadena &#8220;hello world&#8221;. Esto puede hacerse mediante el comando<code>xgettext</code>, o mediante un editor gráfico como <a href="http://www.poedit.net/" class="external">poEdit</a>.</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">apt-get</span> <span class="kw2">install</span> poedit</div></div>
<h3>Creación del catálogo con poEdit</h3>
<p>Ante todo debemos saber que la estructura de directorios para guardar los distintos catálogos tiene forma determinada. Por cada traducción se utiliza un directorio. Este generalmente se nombra usando dos letras minúsculas para el idioma, un guión bajo y dos mayúsculas para el país (es_AR, para español de Argentina). Dentro de este directorio debe existir otro con el nombre LC_MESSAGES, el cual será finalmente el directorio que contendrá el catálogo.</p>
<p>La estructura de nuestro ejemplo será</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">.<br />
<span class="sy0">|</span>-- locale<br />
<span class="sy0">|</span> &nbsp; <span class="sy0">`</span>-- es_AR<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; <span class="sy0">`</span>-- LC_MESSAGES<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">|</span>-- messages.mo<br />
<span class="sy0">|</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sy0">`</span>-- messages.po<br />
<span class="sy0">`</span>-- index.php</div></div>
<p>El archivo<code>messages.mo</code>es la versión compilada de<code>messages.po</code>y el que usará PHP para obtener la traducción.</p>
<p>Iniciemos poEdit. La primera vez nos preguntará por nuestro nombre y correo electrónico. Estos datos servirán para saber quién fue el último traductor que modificó el catálogo. Una vez en la ventana principal vamos a File -> New catalog. Seleccionamos el idioma (Español en este caso), el país y el código de caracteres tanto para el catálogo como para la fuente de datos desde la que obtendremos el listado de cadenas que requieren traducción. En la solapa Paths debemos colocar en &#8216;Base path&#8217; la ruta completa al directorio base de archivos php (conteniendo las cadenas mencionadas anteriormente) y, debajo, en el cuadro &#8216;Paths&#8217; agregar una entrada con &#8216;.&#8217; indicando que se debe utilizar el directorio ingresado anteriormente. Al hacer click en OK aparecerá un cuadro de diálogo para guardar el nuevo catálogo. Navegamos hasta el directorio LC_MESSAGES y guardamos el archivo como messages.po. poEdit escaneará el directorio ingresado en Paths y extraerá todos las cadenas gettext. Ahora queda simplemente realizar la traducción y guardar el archivo. Al guardarlo, poEdit lo compilará y generará el .mo que finalmente usará PHP.</p>
<p>Ahora, modificaremos index.php para setear el locale</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"># @file: index.php<br />
<span class="kw2">&lt;?php</span><br />
<span class="re0">$language</span> <span class="sy0">=</span> <span class="st_h">'es_AR.UTF-8'</span><span class="sy0">;</span><br />
<a href="http://www.php.net/putenv"><span class="kw3">putenv</span></a><span class="br0">&#40;</span><span class="st0">&quot;LANG=<span class="es4">$language</span>&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
<a href="http://www.php.net/setlocale"><span class="kw3">setlocale</span></a><span class="br0">&#40;</span>LC_ALL<span class="sy0">,</span> <span class="st0">&quot;&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$domain</span> <span class="sy0">=</span> <span class="st0">&quot;messages&quot;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/bindtextdomain"><span class="kw3">bindtextdomain</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="sy0">,</span> <span class="st0">&quot;./locale&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/bind_textdomain_codeset"><span class="kw3">bind_textdomain_codeset</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="sy0">,</span> <span class="st_h">'UTF-8'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/textdomain"><span class="kw3">textdomain</span></a><span class="br0">&#40;</span><span class="re0">$domain</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> <a href="http://www.php.net/_"><span class="kw3">_</span></a><span class="br0">&#40;</span><span class="st0">&quot;hello world&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="sy1">?&gt;</span></div></td></tr></tbody></table></div>
<p>Aun nos queda un paso y es comprobar que tengamos dicho locale habilitado en nuestro sistema. Esto lo hacemos mirando la salida de</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">locale <span class="re5">-a</span></div></div>
<p>Si no tenemos habilitado el charset es_AR.UTF8, ejecutamos</p>
<div class="codecolorer-container bash " style="overflow:auto;white-space:nowrap;width:435px"><div class="bash codecolorer" style="font-family:Monaco,Lucida Console,monospace">locale-gen es_AR.UTF-<span class="nu0">8</span></div></div>
<p>En este punto la salida del script debería ser la traducción que hicimos al español.</p>
<h3>Tip</h3>
<p>Para casos en que la cadena a traducir contenga variables, podemos utilizar esta función:</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> __<span class="br0">&#40;</span><span class="re0">$string</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$arg</span> <span class="sy0">=</span> <a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">1</span> <span class="sy0">;</span> <span class="re0">$i</span> <span class="sy0">&lt;</span> <a href="http://www.php.net/func_num_args"><span class="kw3">func_num_args</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$arg</span><span class="br0">&#91;</span><span class="br0">&#93;</span> <span class="sy0">=</span> <a href="http://www.php.net/func_get_arg"><span class="kw3">func_get_arg</span></a><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; <span class="kw1">return</span> <a href="http://www.php.net/vsprintf"><span class="kw3">vsprintf</span></a><span class="br0">&#40;</span><a href="http://www.php.net/gettext"><span class="kw3">gettext</span></a><span class="br0">&#40;</span><span class="re0">$string</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="re0">$arg</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="re0">$total</span> <span class="sy0">=</span> <span class="nu0">400</span><span class="sy0">;</span><br />
<a href="http://www.php.net/print"><span class="kw3">print</span></a> __<span class="br0">&#40;</span><span class="st0">&quot;results <span class="es6">%d</span> - <span class="es6">%d</span> of about <span class="es6">%d</span>&quot;</span><span class="sy0">,</span> <span class="nu0">1</span><span class="sy0">,</span> <span class="nu0">20</span><span class="sy0">,</span> <span class="re0">$total</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>La traducción podría quedar</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">resultados %d - %d de aproximadamente %d</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/03/gnu-gettext-con-php5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Code Golf &#8211; Saving Time</title>
		<link>http://blog.calcifer.com.ar/2009/02/code-golf-saving-time/</link>
		<comments>http://blog.calcifer.com.ar/2009/02/code-golf-saving-time/#comments</comments>
		<pubDate>Mon, 09 Feb 2009 19:08:36 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/?p=187</guid>
		<description><![CDATA[Code Golf es un sitio donde se juega a resolver problemas informáticos en la menor cantidad posible de pulsaciones de tecla. Para ello pueden utilizarse lenguajes como Perl, PHP, Python y Ruby. Quien resuelva el desafío en menor cantidad de keystrokes es quien tendrá mayor puntaje.
Me anoté en uno llamado Saving Time y llegué al [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://codegolf.com" class="external">Code Golf</a> es un sitio donde se juega a resolver problemas informáticos en la menor cantidad posible de pulsaciones de tecla. Para ello pueden utilizarse lenguajes como Perl, PHP, Python y Ruby. Quien resuelva el desafío en menor cantidad de <em>keystrokes</em> es quien tendrá mayor puntaje.</p>
<p>Me anoté en uno llamado <a href="http://codegolf.com/saving-time" class="external">Saving Time</a> y llegué al <a href="http://codegolf.com/leaderboard/competition/saving-time/php" class="external">puesto 20 de PHP</a>, con 245 keystrokes. (<strong>2009-03-27: Aunque ahora me encuentro en el 22, malditos nerds!</strong>)</p>
<p>El desafío consiste en crear la cara de un reloj analógico partiendo de una hora dada en formato<code>hh:mm</code>. Algunas de las reglas son</p>
<ul>
<li>La hora dada en hh:mm se representa con una &#8216;h&#8217; minúscula.</li>
<li>La hora que indica los minutos dados en hh:mm se representa con una &#8216;m&#8217; minúscula.</li>
<li>Cuando hora y minutos coinciden en la misma posición se representa con una &#8216;x&#8217; minúscula.</li>
<li>El resto de las horas se representan con una &#8216;o&#8217; minúscula.</li>
<li>Los minutos deben redondearse al múltiplo de 5 más cercano (23 se convierte en 20, 39 en 35, etc.)</li>
</ul>
<h3>Salida del programa</h3>
<p><iframe src="/devel/code-golf/saving_time.php" width="400" height="270" frameborder="0"></iframe></p>
<h3>Código</h3>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="sy1">&lt;?</span><span class="re0">$f</span><span class="sy0">=</span><span class="st0">&quot;874D1F0D1748110202020201&quot;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/list"><span class="kw3">list</span></a><span class="br0">&#40;</span><span class="re0">$h</span><span class="sy0">,</span><span class="re0">$m</span><span class="br0">&#41;</span><span class="sy0">=</span><a href="http://www.php.net/split"><span class="kw3">split</span></a><span class="br0">&#40;</span><span class="st_h">':'</span><span class="sy0">,</span><a href="http://www.php.net/fgets"><span class="kw3">fgets</span></a><span class="br0">&#40;</span>STDIN<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="kw1">if</span><span class="br0">&#40;</span><span class="re0">$h</span><span class="sy0">&gt;=</span><span class="nu0">12</span><span class="br0">&#41;</span><span class="re0">$h</span><span class="sy0">-=</span><span class="nu0">12</span><span class="sy0">;</span><br />
<span class="re0">$m</span><span class="sy0">=</span><a href="http://www.php.net/floor"><span class="kw3">floor</span></a><span class="br0">&#40;</span><span class="re0">$m</span><span class="sy0">/</span><span class="nu0">5</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="re0">$a</span><span class="sy0">=</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">12</span><span class="sy0">;</span><br />
<span class="kw1">while</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="br0">&#123;</span><span class="re0">$a</span><span class="sy0">+=</span><span class="re0">$i</span><span class="sy0">%</span><span class="nu19">2</span>?<span class="re0">$i</span><span class="sy0">:-</span><span class="re0">$i</span><span class="sy0">;</span><br />
<a href="http://www.php.net/echo"><span class="kw3">echo</span></a> <a href="http://www.php.net/str_pad"><span class="kw3">str_pad</span></a><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span><span class="sy0">,</span><a href="http://www.php.net/hexdec"><span class="kw3">hexdec</span></a><span class="br0">&#40;</span><span class="re0">$f</span><span class="br0">&#123;</span><span class="sy0">--</span><span class="re0">$i</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">.</span><br />
<span class="br0">&#40;</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">==</span><span class="re0">$h</span><span class="br0">&#41;</span>?<span class="br0">&#40;</span><span class="re0">$h</span><span class="sy0">==</span><span class="re0">$m</span>?<span class="st_h">'x'</span><span class="sy0">:</span><span class="st_h">'h'</span><span class="br0">&#41;</span><span class="sy0">:</span><span class="br0">&#40;</span><span class="re0">$a</span><span class="sy0">==</span><span class="re0">$m</span>?<span class="st_h">'m'</span><span class="sy0">:</span><span class="st_h">'o'</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">.</span><br />
<a href="http://www.php.net/str_repeat"><span class="kw3">str_repeat</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es1">\n</span>&quot;</span><span class="sy0">,</span><span class="re0">$f</span><span class="br0">&#123;</span><span class="re0">$i</span><span class="sy0">+</span><span class="nu0">12</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><span class="br0">&#125;</span><span class="sy1">?&gt;</span></div></div>
<p>El string hexadecimal $f contiene el formato necesario para &#8220;dibujar&#8221; el reloj. Para interpretarlo es necesario dividirlo en dos mitades. La primera mitad contiene, en cada caracter hexadecimal, la distancia a la que se encuentra respecto de su elemento anterior, que puede ser el número de la izquierda o un salto de línea. De aquí surge el por qué de haber usado el sistema hexadecimal: el espacio mayor a representar es 15. En la segunda mitad cada caracter representa la cantidad de saltos de línea que preceden al caracter.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2009/02/code-golf-saving-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Validate an E-Mail Address with PHP</title>
		<link>http://blog.calcifer.com.ar/2008/07/validate-an-e-mail-address-with-php/</link>
		<comments>http://blog.calcifer.com.ar/2008/07/validate-an-e-mail-address-with-php/#comments</comments>
		<pubDate>Tue, 08 Jul 2008 19:58:01 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regex]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2008/07/08/validate-an-e-mail-address-with-php/</guid>
		<description><![CDATA[From ILoveJackDaniel&#8217;s
function check_email_address&#40;$email&#41; &#123;
&#160; // First, we check that there's one @ symbol, 
&#160; // and that the lengths are right.
&#160; if &#40;!ereg&#40;&#34;^[^@]{1,64}@[^@]{1,255}$&#34;, $email&#41;&#41; &#123;
&#160; &#160; // Email invalid because wrong number of characters 
&#160; &#160; // in one section or wrong number of @ symbols.
&#160; &#160; return false;
&#160; &#125;
&#160; // Split it into sections [...]]]></description>
			<content:encoded><![CDATA[<p class="from">From <a href="http://www.ilovejackdaniels.com/php/email-address-validation" class="linkexternal">ILoveJackDaniel&#8217;s</a></p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px;height:500px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> check_email_address<span class="br0">&#40;</span><span class="re0">$email</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; <span class="co1">// First, we check that there's one @ symbol, </span><br />
&nbsp; <span class="co1">// and that the lengths are right.</span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><a href="http://www.php.net/ereg"><span class="kw3">ereg</span></a><span class="br0">&#40;</span><span class="st0">&quot;^[^@]{1,64}@[^@]{1,255}$&quot;</span><span class="sy0">,</span> <span class="re0">$email</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="co1">// Email invalid because wrong number of characters </span><br />
&nbsp; &nbsp; <span class="co1">// in one section or wrong number of @ symbols.</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="co1">// Split it into sections to make life easier</span><br />
&nbsp; <span class="re0">$email_array</span> <span class="sy0">=</span> <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">&#40;</span><span class="st0">&quot;@&quot;</span><span class="sy0">,</span> <span class="re0">$email</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="re0">$local_array</span> <span class="sy0">=</span> <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">&#40;</span><span class="st0">&quot;.&quot;</span><span class="sy0">,</span> <span class="re0">$email_array</span><span class="br0">&#91;</span><span class="nu0">0</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span> <span class="sy0">&lt;</span> <a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$local_array</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><a href="http://www.php.net/ereg"><span class="kw3">ereg</span></a><span class="br0">&#40;</span><span class="st0">&quot;^(([A-Za-z0-9!#$%&amp;'*+/=?^_`{|}~-][A-Za-z0-9!#$%&amp;'*+/=?^_`{|}~\.-]{0,63})|(<span class="es1">\&quot;</span>[^(\\|<span class="es1">\&quot;</span>)]{0,62}<span class="es1">\&quot;</span>))$&quot;</span><span class="sy0">,</span> <span class="re0">$local_array</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="co1">// Check if domain is IP. If not, </span><br />
&nbsp; <span class="co1">// it should be valid domain name</span><br />
&nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><a href="http://www.php.net/ereg"><span class="kw3">ereg</span></a><span class="br0">&#40;</span><span class="st0">&quot;^\[?[0-9\.]+\]?$&quot;</span><span class="sy0">,</span> <span class="re0">$email_array</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="re0">$domain_array</span> <span class="sy0">=</span> <a href="http://www.php.net/explode"><span class="kw3">explode</span></a><span class="br0">&#40;</span><span class="st0">&quot;.&quot;</span><span class="sy0">,</span> <span class="re0">$email_array</span><span class="br0">&#91;</span><span class="nu0">1</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$domain_array</span><span class="br0">&#41;</span> <span class="sy0">&lt;</span> <span class="nu0">2</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span> <span class="co1">// Not enough parts to domain</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">for</span> <span class="br0">&#40;</span><span class="re0">$i</span> <span class="sy0">=</span> <span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span> <span class="sy0">&lt;</span> <a href="http://www.php.net/sizeof"><span class="kw3">sizeof</span></a><span class="br0">&#40;</span><span class="re0">$domain_array</span><span class="br0">&#41;</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!</span><a href="http://www.php.net/ereg"><span class="kw3">ereg</span></a><span class="br0">&#40;</span><span class="st0">&quot;^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]+))$&quot;</span><span class="sy0">,</span> <span class="re0">$domain_array</span><span class="br0">&#91;</span><span class="re0">$i</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="kw2">false</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="kw1">return</span> <span class="kw2">true</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2008/07/validate-an-e-mail-address-with-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pattern Singleton en PHP4</title>
		<link>http://blog.calcifer.com.ar/2007/07/pattern-singleton-en-php4/</link>
		<comments>http://blog.calcifer.com.ar/2007/07/pattern-singleton-en-php4/#comments</comments>
		<pubDate>Mon, 30 Jul 2007 12:44:51 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2007/07/30/pattern-singleton-en-php4/</guid>
		<description><![CDATA[A pesar de sus limitaciones en cuanto a orientación a objetos, PHP4 permite implementar un pattern del tipo Singleton.
Por defecto, en PHP4 (y a diferencia de PHP5) los objetos se devuelven/asignan por valor (una copia), por ello es necesario indicar expresamente que deseamos devolver/asignar una referencia del objeto en cuestión.
Una de las formas más elegantes [...]]]></description>
			<content:encoded><![CDATA[<p>A pesar de sus limitaciones en cuanto a orientación a objetos, PHP4 permite implementar un pattern del tipo Singleton.</p>
<p>Por defecto, en PHP4 (y a diferencia de PHP5) los objetos se devuelven/asignan por valor (una copia), por ello es necesario indicar expresamente que deseamos devolver/asignar una referencia del objeto en cuestión.</p>
<p>Una de las formas más elegantes de implemetar este pattern es:</p>
<div class="codecolorer-container php " style="overflow:auto;white-space:nowrap;width:435px;height:600px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="co1">// Clase de la cual deseamos que exista</span><br />
<span class="co1">// una única instancia en todo el programa</span><br />
<span class="kw2">class</span> Config<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="kw2">var</span> <span class="re0">$message</span> <span class="sy0">=</span> <span class="kw2">null</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp;<span class="kw2">function</span> set<span class="br0">&#40;</span><span class="re0">$message</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">message</span> <span class="sy0">=</span> <span class="re0">$message</span><span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp;<span class="kw2">function</span> get<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$this</span><span class="sy0">-&gt;</span><span class="me1">message</span><span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="co1">// Pattern que se ocupará de devolver</span><br />
<span class="co1">// la única instancia de la clase Config</span><br />
<span class="kw2">class</span> Singleton<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="co1">// Método que devuelve una referencia al objeto</span><br />
&nbsp; &nbsp;<span class="kw2">function</span> <span class="sy0">&amp;</span>get<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/static"><span class="kw3">static</span></a> <span class="re0">$instance</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span> <span class="sy0">!</span> <a href="http://www.php.net/isset"><span class="kw3">isset</span></a><span class="br0">&#40;</span><span class="re0">$instance</span><span class="br0">&#41;</span> <span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="re0">$instance</span> <span class="sy0">=</span> <span class="kw2">new</span> Config<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://www.php.net/print"><span class="kw3">print</span></a> <span class="st0">&quot;instancia creada.<span class="es1">\n</span>&quot;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">return</span> <span class="re0">$instance</span><span class="sy0">;</span> &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<span class="br0">&#125;</span><br />
<br />
<span class="co1">// Forma de uso</span><br />
<span class="re0">$config</span> <span class="sy0">=&amp;</span> Singleton<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">set</span><span class="br0">&#40;</span><span class="st_h">'hello world.'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/printf"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es6">%s</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="re0">$config</span> <span class="sy0">=&amp;</span> Singleton<span class="sy0">::</span><span class="me2">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<a href="http://www.php.net/printf"><span class="kw3">printf</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es6">%s</span><span class="es1">\n</span>&quot;</span><span class="sy0">,</span> <span class="re0">$config</span><span class="sy0">-&gt;</span><span class="me1">get</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div></td></tr></tbody></table></div>
<p>Salida del programa</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">instancia creada.<br />
hello world.<br />
hello world.</div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2007/07/pattern-singleton-en-php4/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comfortable editing with VIM</title>
		<link>http://blog.calcifer.com.ar/2006/10/comfortable-editing-with-vim/</link>
		<comments>http://blog.calcifer.com.ar/2006/10/comfortable-editing-with-vim/#comments</comments>
		<pubDate>Mon, 30 Oct 2006 18:21:32 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2006/10/30/comfortable-editing-with-vim/</guid>
		<description><![CDATA[Tomado del blog de Tobias Schlitt
Next occurrence of a word
If you hit*in command mode and your cursor resides on a word, you are taken to the next occurrence of the word. This is quite nice, if you like to know, where a function is called again.
Find matching brace
VIM 7.0 luckily highlights matching parenthesis, if your [...]]]></description>
			<content:encoded><![CDATA[<p class="from">Tomado del blog de <a href="http://schlitt.info/applications/blog/index.php?/archives/488-Comfortable-PHP-editing-with-VIM-5.html" title="" class="linkexternal">Tobias Schlitt</a></p>
<h3>Next occurrence of a word</h3>
<p>If you hit<code>*</code>in command mode and your cursor resides on a word, you are taken to the next occurrence of the word. This is quite nice, if you like to know, where a function is called again.</p>
<h3>Find matching brace</h3>
<p>VIM 7.0 luckily highlights matching parenthesis, if your cursor resides on a brace, but sometimes you need to quickly jump to that matching brace. You can achieve this by hitting the<code>%</code>sign in command mode.</p>
<h3>Repeat the last change</h3>
<p>It often occurs, that you need to perform 1 change several times, but not often enough to write a short script or to address the changes with a complex regex. In those cases you can perform the change once, move the cursor to the next place and hit the<code>.</code>(dot) char, in command mode.</p>
<p><span id="more-75"></span></p>
<h3>Enhanced functionality with external programs</h3>
<p>This tip is quite commonly known, but I repeat it here, because it&#8217;s really helpful: Although VIM has a huge set of useful functions, it does not have everything. If you don&#8217;t find a utility in VIM, you can simply use extern shell tools to perform certain tasks, by using<code>:!&lt;command&gt;</code>in command or visual mode. For example sorting a range of lines can easily be achieved with the following 2 steps: 1. Select the lines to sort in visual mode. 2. Type<code>:!sort</code>and hit return.</p>
<h3>Indenting and unindeting</h3>
<p>Especially when editing code, it happens often, that you have to indent/unindent a code block. If you use VIM&#8217;s auto-indenting features (like used by my .vimrc), VIM can do that job for you, too. Simply select the lines to (un-)indent in visual mode and hit<code>&lt;</code>to unindent 1 level or<code>&gt;</code>to indent 1 more level. This also works (as usual in VIM) with quantifiers like 4> to indent 4 more levels.</p>
<h3>Remote file editing</h3>
<p>Often you have to quickly edit a file on a remote server. Usually you SSH to that server or mount a remote file system locally, edit the desired file and quit the session again. VIM allows you to do this in 1 step, using SCP. On your shell type<code>vim scp://user@server//path/to/the/file</code>and VIM will edit the file directly through SCP.</p>
<h3>Recover the last visual selection</h3>
<p>It often happens, that you selected some text in visual mode, e.g. to perform a regex on it. Occasionally your regex is incorrect and you have to revert the changes or they don&#8217;t even happen. What you then need is to re-select the text portion again, which might take quite a long time, if you deal with large files. Hitting<code>gv</code>in command mode, takes that work from you and selects the last visual selection again.</p>
<h3>Grep within VIM</h3>
<p>Refactoring happens quite often in dynamic projects. &#8220;Real&#8221; IDE&#8217;s offer a lot of tools for this task. While VIM does not, you can enhance your refactoring process a lot with using regex and this tiny tip: To grep through a lot of files for certain strings and then perform changes on each occurrence, vim offers the<code>:grep command</code>.<code>:grep &lt;string&gt; &lt;files&gt;</code>and VIM will store the list of changes for you and :cn will take you to the next occurance of your string. The :grep command utilizes your systems instance of grep, or a custom command stored in the grepprg configuration variable. There is also an internal implementation of grep available in VIM, which you can use with<code>:vimgrep /&lt;regex&gt;/&lt;flags&gt; &lt;files&gt;</code>. The benefit of the external implementation is, that you can easily customize the command to use, e.g. if you need to ignore certain directories while grepping recursively (for instance .svn dirs). You can also get a list of all occurrences of your grep command, using :ll, which is actually a feature of VIMs quickfix tool. Simply select the next entry you want to jump to and hit return in the location list.</p>
<h3>Placeholders in commands</h3>
<p>Who doesn&#8217;t know the case, where you need to open a file in the same directory, the currently edited file resides in? Sure, you can simply use<code>:split &lt;file&gt;</code>, but if your current working directory is far away from the edited file, you possibly will have to type a long long path again. VIM offers you, to replace certain placeholders in commands automatically, most important:<code>%</code>is replaced with the actual file name (so,<code>:split %</code>will open a new window editing the current file &#8211; I know that just<code>:split</code>does the same, but it&#8217;s a nice example to show what<code>%</code>does). So, how does this help in the described case? The replacement text can also be modified by certain modifiers, like<code>:h</code>, which removes the last portion of a file path (the file name). For instance if you currently edit<code>/home/dotxp/dev/ez/ezc/trunk/ConsoleTools/src/table.php</code>and want to split to<code>/home/dotxp/dev/ez/ezc/trunk/ConsoleTools/src/output.php</code>you can do this easily using<code>:split %:h/output.php</code>. Another useful modifier is<code>:s?&lt;regex&gt;?&lt;replacement&gt;?</code>, which obviously uses a regex to modify the given path. Unlikely the usual replacement command<code>:s</code>, you need to specify the global modifier<code>g</code>before the regex instead of doing so after it. A short example:<code>:split %:gs?trunk?/releases/1.1/?</code>will split to the file table.php of ConsoleTools release 1.1.</p>
<h3>Emergency help</h3>
<p>Appending an exclamation mark (<code>!</code>) to a command (<code>:<command>!</code>) forces VIM to execute the command, even if it might be dangerous to do so. Quite useless, but still funny is<code>:help!</code>.</p>
<h3>Rewrap my text</h3>
<p>I reached a stage, where do not only edit my source code using VIM, but mainly every other kind of text data (like documentation, todo lists, etc.), because I&#8217;m simply so used to its features. When editing plain text, the automatic wrap features (e.g. textwidth) of VIM are quite useful. In some cases, you might edit text later and therefore destroy a nicely wrapped text block. VIM can easily re-perform the wrapping for you: Select the text block in visual mode (using &lt;SHIFT&gt;+&lt;v&gt;) and hit<code>&lt;g&gt;&lt;q&gt;</code>.</p>
<h3>Uppercase letters</h3>
<p>There are a lot of helpful shortcuts on your keyboard, which you might not know about. Every VIM user should now, that<code>&lt;d&gt;</code>deletes something,<code>&lt;y&gt;</code>(yank) copies something and<code>&lt;c&gt;</code>changes something (delete and start inserting) in VIM (all in command mode). Furthermore, most people know that e.g.<code>&lt;d&gt;&lt;w&gt;</code>deletes the next word, etc.. What I did not know for a long time was, that<code>&lt;D&gt;</code>, &lt;Y&#038;gt</code>; and<code>&lt;C&gt;</code>are shortcuts to perform the desired operation until the end of the current line. For instance, simply type<code>&lt;C&gt;</code>to change the contents of the current line from your cursors position on.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2006/10/comfortable-editing-with-vim/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Generando Captchas con PHP</title>
		<link>http://blog.calcifer.com.ar/2006/10/generando-captchas-con-php/</link>
		<comments>http://blog.calcifer.com.ar/2006/10/generando-captchas-con-php/#comments</comments>
		<pubDate>Fri, 06 Oct 2006 04:12:28 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2006/10/06/generando-captchas-con-php/</guid>
		<description><![CDATA[Captcha es el acrónimo de Completely Automated Public Turing test to tell Computers and Humans Apart (Prueba de Turing pública y automática para diferenciar a máquinas y humanos).
Se trata de una prueba desafío-respuesta utilizada en computación para determinar cuándo el usuario es o no humano. Como el test es controlado por una máquina en lugar [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Captcha</strong> es el acrónimo de <em><strong>C</strong>ompletely <strong>A</strong>utomated <strong>P</strong>ublic <a href="http://es.wikipedia.org/wiki/Prueba_de_Turing" title="Prueba de Turing en Wikipedia" class="linkwikipedia"><strong>T</strong>uring test</a> to tell <strong>C</strong>omputers and <strong>H</strong>umans <strong>A</strong>part</em> (Prueba de Turing pública y automática para diferenciar a máquinas y humanos).</p>
<p>Se trata de una prueba desafío-respuesta utilizada en computación para determinar cuándo el usuario es o no humano. Como el test es controlado por una máquina en lugar de un humano como en la prueba de turing, también se denomina Prueba de Turing inversa.</p>
<h2>Clase Captcha</h2>
<p>Esta es una clase que hice para <a href="http://www.lamarchaperonista.com.ar/pedidos" title="" class="linkexternal">www.lamarchaperonista.com.ar</a> que genera captchas usando fuentes True Type (.ttf). La clase tiene varios métodos para personalizar el captcha, generar el código y seteralo en una variable de sesión de PHP.</p>
<p>La forma de usarla es realmente simple. Sólo hay que crear un script que contenga la clase y devuelva el captcha. Este mismo script será el encargado de generar el código y guardarlo en una variable de sesión:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px;height:300px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// File: getCaptcha.php<br />
requiere_once('Capcha.php');<br />
session_start();<br />
<br />
// Creo un captcha de 150 x 50 px<br />
$captcha = new Captcha(150, 50);<br />
<br />
// Creo y seteo en $_SESSION el código de 4 caracteres<br />
$captcha-&gt;setSessionVar(4);<br />
<br />
// Seteo la fuente TTF a usar<br />
if ($captcha-&gt;setFontFile('ArsleGothic.ttf')) {<br />
<br />
&nbsp; &nbsp;// Seteo el tamaño de la tipografía<br />
&nbsp; &nbsp;$captcha-&gt;setFontSize(24);<br />
<br />
&nbsp; &nbsp;// El color<br />
&nbsp; &nbsp;$captcha-&gt;setFontColorWeb('716052');<br />
<br />
&nbsp; &nbsp;// Envío la imagen<br />
&nbsp; &nbsp;$captcha-&gt;sendCaptcha();<br />
<br />
}</div></div>
</pre>
<p>Al ser llamado desde otra página (como esta), mediante</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">&amp;lt;img scr=&quot;getCapcha.php&quot;/&amp;gt;</div></div>
<p>, el script generará un captcha como el siguiente:</p>
<p class="center"><img src="http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=1" alt="Captcha generado con la clase Captcha.php" name="captcha1"/><br />
<a href="javascript:;" onclick="document.images.captcha1.src='http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=1&amp;date='+(new Date()).getTime()">generar nuevo</a></p>
<p>Luego, en el script que controla los datos que vienen del formulario (en el que el captcha fue mostrado), hacemos algo como esto:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">// File: checkForm.php<br />
requiere_once('Capcha.php');<br />
session_start();<br />
<br />
// Creo una instancia de Captcha, pero sin pasarle parámetros,<br />
// ya que no voy a generar ninguna imagen.<br />
$captcha = new Captcha();<br />
<br />
// Traigo el código del captcha (seteado en $_SESSION)<br />
// y lo comparo con el que me vino del formulario<br />
if ( $_POST['codeCaptcha'] == $captcha-&gt;getCode() ) {<br />
<br />
&nbsp; &nbsp;// lo que haré en caso de coincidir los códigos.<br />
<br />
}<br />
else {<br />
<br />
&nbsp; &nbsp;// lo que haré en caso de NO coincidir los códigos.<br />
<br />
}</div></div>
</pre>
<h2>Otro ejemplo</h2>
<p>La clase tiene varios métodos más para setear las distintas propiedades del captcha, como el color de fondo, la densidad del ruido (las lineas que aparecen detras del texto) y el color del mismo.</p>
<p class="center"><img src="http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=2" alt="Captcha generado con la clase Captcha.php" name="captcha2"/><br />
<a href="javascript:;" onclick="document.images.captcha2.src='http://blog.calcifer.com.ar/devel/captcha/getCaptcha.php?id=2&amp;date='+(new Date()).getTime()">generar nuevo</a></p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">$captcha = new Captcha(280, 70);<br />
$captcha-&gt;setSessionVar(6);<br />
if ($captcha-&gt;setFontFile('BagadBold.ttf')) {<br />
&nbsp; &nbsp;$captcha-&gt;setFontSize(32);<br />
&nbsp; &nbsp;$captcha-&gt;setFontColorWeb('00497B');<br />
&nbsp; &nbsp;$captcha-&gt;setBgColorWeb('5C9FCC');<br />
&nbsp; &nbsp;$captcha-&gt;setNoiseColorWeb('0069B0');<br />
&nbsp; &nbsp;$captcha-&gt;setNoiseFactor(70);<br />
&nbsp; &nbsp;$captcha-&gt;sendCaptcha();<br />
}</div></div>
</pre>
<p>Existen métodos para setear los colores pasando el código hexadecimal, ej.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">setFontColorWeb(&quot;FF0033&quot;)</div></div>
<p>, y para setearlos pasando los valores por cada canal, ej.</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">setFontColor(255,0,51)</div></div>
<p>.</p>
<h2>Archivos y documentación</h2>
<p>El código junto con la documentación pueden bajarse desde aquí: <a href="http://blog.calcifer.com.ar/devel/captcha/Captcha.tar.gz" title="" class="linkcompressfile">Captcha.tar.gz</a><br />
La documentación también puede verse en línea en <a href="http://blog.calcifer.com.ar/devel/captcha/doc" title="" class="linkexternal">http://blog.calcifer.com.ar/devel/captcha/doc</a><br />
Un buen sitio para bajar fuentes TrueType es <a href="http://www.creamundo.com/" title="" class="linkexternal">http://www.creamundo.com/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2006/10/generando-captchas-con-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Función para generar passwords aleatorios</title>
		<link>http://blog.calcifer.com.ar/2006/09/funcion-para-generar-passwords-aleatorios/</link>
		<comments>http://blog.calcifer.com.ar/2006/09/funcion-para-generar-passwords-aleatorios/#comments</comments>
		<pubDate>Sat, 30 Sep 2006 18:13:08 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[None]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[snippets]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2006/09/30/funcion-para-generar-passwords-aleatorios/</guid>
		<description><![CDATA[Vía Intenta
12345678910111213141516171819202122232425function generarClave&#40;$longitud&#41;
&#123;
&#160; &#160;$caracteres=array&#40;&#41;;
&#160; &#160;$clave='';

&#160; &#160;# números
&#160; &#160;for&#40;$i=48; $i&#38;lt;=57; $i++&#41;
&#160; &#160; &#160; array_push&#40;$caracteres, chr&#40;$i&#41;&#41;;

&#160; &#160;# mayúsculas
&#160; &#160;for&#40;$i=65; $i&#38;lt;=90; $i++&#41;
&#160; &#160; &#160; array_push&#40;$caracteres, chr&#40;$i&#41;&#41;;

&#160; &#160;# minúsculas
&#160; &#160;for&#40;$i=97; $i&#38;lt;=122; $i++&#41;
&#160; &#160; &#160; array_push&#40;$caracteres, chr&#40;$i&#41;&#41;;

&#160; &#160;for&#40;$i=0; $i&#38;lt;$longitud; $i++&#41;
&#160; &#160;&#123;
&#160; &#160; &#160; mt_srand&#40;&#40;double&#41;microtime&#40;&#41;*1000000&#41;;
&#160; &#160; &#160; $clave .= $caracteres&#91;mt_rand&#40;0,count&#40;$caracteres&#41;&#41;&#93;;
&#160; &#160;&#125;

&#160; &#160;return $clave;
&#125;
Otra opción es usar el identificador de sesión (session [...]]]></description>
			<content:encoded><![CDATA[<p class="from">Vía <a href="http://www.webintenta.com/funcion-para-generar-passwords-aleatorios.html" class="linkexternal">Intenta</a></p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;width:435px;height:300px"><table cellspacing="0" cellpadding="0"><tbody><tr><td class="line-numbers"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /></div></td><td><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><span class="kw2">function</span> generarClave<span class="br0">&#40;</span><span class="re0">$longitud</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp;<span class="re0">$caracteres</span><span class="sy0">=</span><a href="http://www.php.net/array"><span class="kw3">array</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="re0">$clave</span><span class="sy0">=</span><span class="st_h">''</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp;<span class="co2"># números</span><br />
&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">48</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&amp;</span>lt<span class="sy0">;=</span><span class="nu0">57</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$caracteres</span><span class="sy0">,</span> <a href="http://www.php.net/chr"><span class="kw3">chr</span></a><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp;<span class="co2"># mayúsculas</span><br />
&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">65</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&amp;</span>lt<span class="sy0">;=</span><span class="nu0">90</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$caracteres</span><span class="sy0">,</span> <a href="http://www.php.net/chr"><span class="kw3">chr</span></a><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp;<span class="co2"># minúsculas</span><br />
&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">97</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&amp;</span>lt<span class="sy0">;=</span><span class="nu0">122</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/array_push"><span class="kw3">array_push</span></a><span class="br0">&#40;</span><span class="re0">$caracteres</span><span class="sy0">,</span> <a href="http://www.php.net/chr"><span class="kw3">chr</span></a><span class="br0">&#40;</span><span class="re0">$i</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
&nbsp; &nbsp;<span class="kw1">for</span><span class="br0">&#40;</span><span class="re0">$i</span><span class="sy0">=</span><span class="nu0">0</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">&amp;</span>lt<span class="sy0">;</span><span class="re0">$longitud</span><span class="sy0">;</span> <span class="re0">$i</span><span class="sy0">++</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://www.php.net/mt_srand"><span class="kw3">mt_srand</span></a><span class="br0">&#40;</span><span class="br0">&#40;</span>double<span class="br0">&#41;</span><a href="http://www.php.net/microtime"><span class="kw3">microtime</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">*</span><span class="nu0">1000000</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="re0">$clave</span> <span class="sy0">.=</span> <span class="re0">$caracteres</span><span class="br0">&#91;</span><a href="http://www.php.net/mt_rand"><span class="kw3">mt_rand</span></a><span class="br0">&#40;</span><span class="nu0">0</span><span class="sy0">,</span><a href="http://www.php.net/count"><span class="kw3">count</span></a><span class="br0">&#40;</span><span class="re0">$caracteres</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp;<span class="br0">&#125;</span><br />
<br />
&nbsp; &nbsp;<span class="kw1">return</span> <span class="re0">$clave</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></td></tr></tbody></table></div>
<p>Otra opción es usar el identificador de sesión (session id) para obtener la contraseña de él:</p>
<div class="codecolorer-container php blackboard" style="overflow:auto;white-space:nowrap;width:435px"><div class="php codecolorer" style="font-family:Monaco,Lucida Console,monospace"><a href="http://www.php.net/session_start"><span class="kw3">session_start</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="re0">$password</span> <span class="sy0">=</span> <a href="http://www.php.net/substr"><span class="kw3">substr</span></a> <span class="br0">&#40;</span><a href="http://www.php.net/session_id"><span class="kw3">session_id</span></a><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="nu0">0</span><span class="sy0">,</span> <span class="nu0">10</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2006/09/funcion-para-generar-passwords-aleatorios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Client does not support authentication protocol</title>
		<link>http://blog.calcifer.com.ar/2006/08/client-does-not-support-authentication-protocol/</link>
		<comments>http://blog.calcifer.com.ar/2006/08/client-does-not-support-authentication-protocol/#comments</comments>
		<pubDate>Wed, 30 Aug 2006 20:02:41 +0000</pubDate>
		<dc:creator>lvidarte</dc:creator>
				<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.calcifer.com.ar/2006/08/30/client-does-not-support-authentication-protocol/</guid>
		<description><![CDATA[Luego de agregar un nuevo usuario MySQL he tenido el siguiente problema al intentar conectarme a la DB usando PHP4:

Client does not support authentication protocol requested by server;
consider upgrading MySQL client

Buscando llego a: http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html
El problema
The password hashing mechanism was updated in MySQL 4.1 to provide better security and to reduce the risk of passwords being [...]]]></description>
			<content:encoded><![CDATA[<p>Luego de agregar un nuevo usuario MySQL he tenido el siguiente problema al intentar conectarme a la DB usando PHP4:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">Client does not support authentication protocol requested by server;<br />
consider upgrading MySQL client</div></div>
</pre>
<p>Buscando llego a: <a href="http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html" class="linkexternal">http://dev.mysql.com/doc/refman/5.0/en/password-hashing.html</a></p>
<h3>El problema</h3>
<blockquote><p>The password hashing mechanism was updated in MySQL 4.1 to provide better security and to reduce the risk of passwords being intercepted. However, this new mechanism is understood only by MySQL 4.1 (and newer) servers and clients, which can result in some compatibility problems.</p></blockquote>
<p>Hace un tiempo pasé de la versión 4 a la 4.1. Resulta que ahora el hash correspondiente a las passwords se realiza utilizando un nuevo algoritmo que genera un hash de 41 bytes frente al viejo de 16 bytes.</p>
<p>Antes de la versión 4.1 la función</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">PASSWORD()</div></div>
<p>devolvía un hash de 16 bytes:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql&gt; SELECT PASSWORD('mypass');<br />
+--------------------+<br />
| PASSWORD('mypass') |<br />
+--------------------+<br />
| 6f8c114b58f2ce9e &nbsp; |<br />
+--------------------+</div></div>
</pre>
<p>A partir de la versión 4.1 la función</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">PASSWORD()</div></div>
<p>devuelve un hash de 41 bytes:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql&gt; SELECT PASSWORD('mypass');<br />
+-------------------------------------------+<br />
| PASSWORD('mypass') &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|<br />
+-------------------------------------------+<br />
| *6C8989366EAF75BB670AD8EA7A7FC1176A95CEF4 |<br />
+-------------------------------------------+</div></div>
</pre>
<h3>Solución</h3>
<p>Según: <a href="http://dev.mysql.com/doc/refman/5.0/en/php-problems.html" class="linkexternal">Common Problems with MySQL and PHP</a>.</p>
<blockquote><p><strong>Error: Client does not support authentication protocol</strong>: This is most often encountered when trying to use the older mysql extension with MySQL 4.1.1 and later. Possible solutions are: downgrade to MySQL 4.0; switch to PHP 5 and the newer mysqli extension; or configure the MySQL server with &#8211;old-passwords. (See Section A.2.3, “Client does not support authentication protocol”, for more information.)</p></blockquote>
<h3>Otra solución</h3>
<p>La función</p>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">OLD_PASSWORD</div></div>
<p>devuelve el viejo hash de 16 bytes:</p>
<pre>
<div class="codecolorer-container text " style="overflow:auto;white-space:nowrap;width:435px"><div class="text codecolorer" style="font-family:Monaco,Lucida Console,monospace">mysql&gt; SET PASSWORD FOR 'some_user'@'some_host' = OLD_PASSWORD('newpwd');</div></div>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.calcifer.com.ar/2006/08/client-does-not-support-authentication-protocol/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

