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

<channel>
	<title>Felipe Ribeiro</title>
	<atom:link href="http://blog.feliperibeiro.com/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.feliperibeiro.com</link>
	<description></description>
	<pubDate>Mon, 05 Jan 2009 02:03:45 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Caching em PHP com uma técnica &#8220;obscura&#8221; mas muito eficiente</title>
		<link>http://blog.feliperibeiro.com/2008/12/caching-em-php-com-uma-tecnica-obscura-mas-muito-eficiente.html</link>
		<comments>http://blog.feliperibeiro.com/2008/12/caching-em-php-com-uma-tecnica-obscura-mas-muito-eficiente.html#comments</comments>
		<pubDate>Thu, 25 Dec 2008 17:29:41 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[apache]]></category>

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

		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://blog.feliperibeiro.com/2008/12/caching-em-php-com-uma-tecnica-obscura-mas-muito-eficiente.html</guid>
		<description><![CDATA[Caching é fundamental para a escalabilidade de aplicações Web. Existem diversas ferramentas que oferecem diferentes maneiras de se fazer isso, seja no Smarty, no APC, nos diversos frameworks, ou Memcached para os mais drásticos&#8230;
Mas essa é a &#8220;maneira Rasmus Lerdorf&#8221; de se fazer cache com PHP sem nenhuma ferramenta externa e com uma sacada fenomenal.
Para [...]]]></description>
			<content:encoded><![CDATA[<p style="clear: both">Caching é fundamental para a escalabilidade de aplicações Web. Existem diversas ferramentas que oferecem diferentes maneiras de se fazer isso, seja no Smarty, no APC, nos diversos frameworks, ou Memcached para os mais drásticos&#8230;</p>
<p style="clear: both">Mas essa é a &#8220;<a title="Rasmus' trick" href="http://derickrethans.nl/errorhandling/rasmus-trick.html">maneira Rasmus Lerdorf</a>&#8221; de se fazer cache com PHP sem nenhuma ferramenta externa e com uma sacada fenomenal.</p>
<p style="clear: both">Para um servidor Web é <strong>muito</strong> mais rápido servir arquivos estáticos do que esperar que aquele arquivo seja interpretado por algum módulo ou que seja executado em CGI e é isso que esse método faz, gera arquivos estáticos sob demanda, utilizando os recursos que o Apache oferece.</p>
<p style="clear: both">Agora imagine que você tem um site de notícias e quer que elas sejam tratadas como arquivos estáticos, e os links para cada notícia seria algo como:</p>
<p style="clear: both">http://meusite.com.br/noticias/000001.html</p>
<p style="clear: both">1º passo: Setamos nas configurações do Apache para que a página de erro 404 seja um arquivo .php (isso pode ser feito no .htaccess da pasta ou nas configurações do Apache propriamente dito). No caso do .htaccess, basta colocar isso:</p>
<pre><code>
ErrorDocument 404 /noticias/gera_cache.php
</code></pre>
<p style="clear: both">2º passo: Criamos o arquivo gera_cache.php, que irá tratar as requisições que teriam como resposta o erro 404 (Not Found) com o seguinte codigo:</p>
<pre><code>

&lt;?php
    $id = basename($_SERVER['REDIRECT_URL'], '.html');

    /* Acessa a página dinâmica */
    $html = file_get_contents(sprintf("http://meusite.com.br/noticias.php?id=%d",$id));
    /* O ideal é fazer algum tratamento de erros, para evitar a criação de arquivos para ids inválidos */

    /* Exibe o conteúdo */
    header(sprintf('%s 200', $_SERVER['SERVER_PROTOCOL']));
    echo $html;

    /* Salva o conteúdo em um arquivo .html */
    $fp = fopen(sprintf(dirname(__FILE__)."/%d.html", $id), "w");
    fputs($fp, $html);
    fclose($fp);
?&gt;

</code></pre>
<p style="clear: both">Sendo assim, o que vai acontecer:</p>
<p style="clear: both">Quando o usuário acessar pela primeira vez o link <strong>http://meusite.com.br/noticias/000001.html</strong>, o arquivo <strong>/noticias/000001.html</strong> não existirá e o usuário será redirecionado para o <strong>gera_cache.php</strong>. O <strong>gera_cache.php</strong> acessa a página dinâmica que exibe o conteúdo da página com o id passado (000001) e salva em um html. Nos acessos consecutivos ao <strong>http://meusite.com.br/noticias/000001.html</strong> o arquivo existirá e não passará mais pelo PHP.</p>
<p>É uma técnica bem &#8220;<strong>tricky</strong>&#8221; e que precisa de cuidados, por exemplo, você precisa ter uma rotina que expira os arquivos em cache após algum tempo e quando houver alguma alteração em determinada informação que interfere na página que está em cache, para garantir consistência dos dados. Uma maneira muito simples de se fazer isso é usando a função <a href="http://br2.php.net/filectime">filectime</a> do PHP para checar a idade dos arquivos em uma rotina que rodaria em background e apagaria os que fossem mais velhos que o tempo desejado. Mas funciona muito bem!</p>
<p>P.S.: Um artigo que li dizia que apesar dessa técnica ter se tornado pública através do Rasmus, ela foi criada mesmo pelo <a href="http://pear.php.net/account-info.php?handle=ssb">Stig Bakken</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/12/caching-em-php-com-uma-tecnica-obscura-mas-muito-eficiente.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Reportagem do Jornal da Globo sobre falha no IE</title>
		<link>http://blog.feliperibeiro.com/2008/12/reportagem-do-jornal-da-globo-sobre-falha-no-ie.html</link>
		<comments>http://blog.feliperibeiro.com/2008/12/reportagem-do-jornal-da-globo-sobre-falha-no-ie.html#comments</comments>
		<pubDate>Thu, 18 Dec 2008 03:38:59 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

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

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

		<guid isPermaLink="false">http://blog.feliperibeiro.com/2008/12/reportagem-do-jornal-da-globo-sobre-falha-no-ie.html</guid>
		<description><![CDATA[

]]></description>
			<content:encoded><![CDATA[<p style="clear: both"><span style=" display: inline; float: left; margin: 0 10px 10px 0;"><object height="392" width="480"><param name="movie" value="http://video.globo.com/Portal/videos/cda/player/player.swf" /><param name="quality" value="high" /><param name="FlashVars" value="midiaId=937727&#038;autoStart=false&#038;width=480&#038;height=392" /><embed type="application/x-shockwave-flash" src="http://video.globo.com/Portal/videos/cda/player/player.swf" flashvars="midiaId=937727&#038;autoStart=false&#038;width=480&#038;height=392" height="392" quality="high" width="480"></embed></object></span></p>
<p><br class="final-break" style="clear: both" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/12/reportagem-do-jornal-da-globo-sobre-falha-no-ie.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Slides - PHP não é coisa de moleque</title>
		<link>http://blog.feliperibeiro.com/2008/12/slides-php-nao-e-coisa-de-moleque.html</link>
		<comments>http://blog.feliperibeiro.com/2008/12/slides-php-nao-e-coisa-de-moleque.html#comments</comments>
		<pubDate>Fri, 05 Dec 2008 18:01:42 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[eventos]]></category>

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

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

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=168</guid>
		<description><![CDATA[Seguem os slides da miha apresentação no I Encontro de desenvolvedores PHP da Paraíba.
PHP não é coisa de moleque
View SlideShare presentation or Upload your own. (tags: php evangelizacao)

Os outros slides das palestras podem ser vistos aqui:
http://www.slideshare.net/tag/i-encontro-php-pb
]]></description>
			<content:encoded><![CDATA[<p>Seguem os slides da miha apresentação no I Encontro de desenvolvedores PHP da Paraíba.</p>
<div id="__ss_802632" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="PHP não é coisa de moleque" href="http://www.slideshare.net/felipernb/php-no-coisa-de-moleque-presentation?type=powerpoint">PHP não é coisa de moleque</a><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=slides-1228060166778844-9&amp;rel=0&amp;stripped_title=php-no-coisa-de-moleque-presentation" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=slides-1228060166778844-9&amp;rel=0&amp;stripped_title=php-no-coisa-de-moleque-presentation" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a style="text-decoration:underline;" title="View PHP não é coisa de moleque on SlideShare" href="http://www.slideshare.net/felipernb/php-no-coisa-de-moleque-presentation?type=powerpoint">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/php">php</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/evangelizacao">evangelizacao</a>)</div>
</div>
<p>Os outros slides das palestras podem ser vistos aqui:</p>
<p><a href='http://www.slideshare.net/tag/i-encontro-php-pb'>http://www.slideshare.net/tag/i-encontro-php-pb</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/12/slides-php-nao-e-coisa-de-moleque.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Boas notícias</title>
		<link>http://blog.feliperibeiro.com/2008/12/boas-noticias.html</link>
		<comments>http://blog.feliperibeiro.com/2008/12/boas-noticias.html#comments</comments>
		<pubDate>Tue, 02 Dec 2008 00:34:28 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[eventos]]></category>

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

		<category><![CDATA[eventos php]]></category>

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=164</guid>
		<description><![CDATA[Apesar do cansaço e da falta de tempo pra tudo, começo a semana muito alegre com duas coisas que aconteceram:

O encontro do PHP-Paraíba foi um SUCESSO! Parabéns a todos que organizaram!
Sou o vencedor do Innovation Award de Outubro no PHPClasses.org! Parabéns para mim!

Enfim, estou muito ocupado e volto a postar em breve!  
]]></description>
			<content:encoded><![CDATA[<p>Apesar do cansaço e da falta de tempo pra tudo, começo a semana muito alegre com duas coisas que aconteceram:</p>
<ul>
<li>O encontro do PHP-Paraíba foi um SUCESSO! Parabéns a todos que organizaram!</li>
<li>Sou o vencedor do Innovation Award de Outubro no PHPClasses.org! Parabéns para mim!</li>
</ul>
<p>Enfim, estou muito ocupado e volto a postar em breve! <img src='http://blog.feliperibeiro.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/12/boas-noticias.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Comecei a me preparar pra prova de ZCE!</title>
		<link>http://blog.feliperibeiro.com/2008/11/comecei-a-me-preparar-pra-prova-de-zce.html</link>
		<comments>http://blog.feliperibeiro.com/2008/11/comecei-a-me-preparar-pra-prova-de-zce.html#comments</comments>
		<pubDate>Sun, 09 Nov 2008 13:30:47 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=156</guid>
		<description><![CDATA[Faz tempo que venho falando que vou fazer a prova, quando o dólar estava baixo eu deixei passar, e agora as coisas complicaram&#8230; Mas mesmo assim estou decidido a fazer no máximo em Janeiro.
Meu amigo Marcelo Schmidt, me &#8220;doou&#8221; os simulados que ele não precisou mais fazer quando tirou a certificação dele.
E hoje eu fiz [...]]]></description>
			<content:encoded><![CDATA[<p>Faz tempo que venho falando que vou fazer a prova, quando o dólar estava baixo eu deixei passar, e agora as coisas complicaram&#8230; Mas mesmo assim estou decidido a fazer no máximo em Janeiro.</p>
<p>Meu amigo <a href="http://www.marceloschmidt.com">Marcelo Schmidt</a>, me &#8220;doou&#8221; os simulados que ele não precisou mais fazer quando tirou a certificação dele.</p>
<p>E hoje eu fiz um só pra ver como está o meu nível e foi melhor do que eu esperava! No guia de certificaçao só li até metade do capítulo &#8220;String and Patterns&#8221;, então já esperava me dar mal em coisas como Streams, que nunca mexi de verdade, só leitura e escrita simples em arquivos, e em segurança que tenho conhecimentos gerais mas não específicos de configuração do PHP. Mas enfim&#8230; estou bem satisfeito com o resultado, vou dar uma lida no que não me dei tão bem pra no próximo simulado conseguir tudo &#8220;excelent&#8221; e marcar a prova! <img src='http://blog.feliperibeiro.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p style="text-align: center; "><img class="size-full wp-image-159 aligncenter" title="picture-11" src="http://blog.feliperibeiro.com/wp-content/uploads/2008/11/picture-11.png" alt="" width="500" height="466" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/11/comecei-a-me-preparar-pra-prova-de-zce.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Oportunidade - Programador de Interfaces</title>
		<link>http://blog.feliperibeiro.com/2008/10/oportunidade-programador-de-interfaces.html</link>
		<comments>http://blog.feliperibeiro.com/2008/10/oportunidade-programador-de-interfaces.html#comments</comments>
		<pubDate>Fri, 24 Oct 2008 19:15:27 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[desenvolvimento de software]]></category>

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

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

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

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

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=144</guid>
		<description><![CDATA[A startup que trabalho (shoprizer.com) tem uma equipe formada por Jedis (onde eu sou o Mestre Yoda :-D), que trabalham com PHP Hardcore e está precisando agora de um NINJA, um programador de interfaces, para trabalho remoto.  Os requisitos são:

XHTML, CSS, Web standards
Javascript/AJAX
PHP básico/intermediário - só o necessário para a integração da lógica existente [...]]]></description>
			<content:encoded><![CDATA[<p>A startup que trabalho (shoprizer.com) tem uma equipe formada por Jedis (onde eu sou o Mestre Yoda :-D), que trabalham com PHP Hardcore e está precisando agora de um NINJA, um programador de interfaces, para trabalho remoto.  Os requisitos são:</p>
<ul>
<li>XHTML, CSS, Web standards</li>
<li>Javascript/AJAX</li>
<li>PHP básico/intermediário - só o necessário para a integração da lógica existente com a interface a ser feita.</li>
<li>Smarty</li>
<li>Disponibilidade de 20 horas semanais - flexíveis.</li>
<li>Inglês básico para leitura e escrita</li>
<li>Conhecimento de princípios de Usabilidade</li>
<li>Precisa ter o espírito de startup!</li>
</ul>
<p>Se você está interessado, mande seu CV com links do seu portfolio para van2br@yahoo.com, atenção à Vanessa.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/10/oportunidade-programador-de-interfaces.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Review e slides do CONAPHP</title>
		<link>http://blog.feliperibeiro.com/2008/10/review-e-slides-do-conaphp.html</link>
		<comments>http://blog.feliperibeiro.com/2008/10/review-e-slides-do-conaphp.html#comments</comments>
		<pubDate>Wed, 22 Oct 2008 12:59:19 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[desenvolvimento de software]]></category>

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

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

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

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

		<category><![CDATA[web 2.0]]></category>

		<category><![CDATA[web services]]></category>

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=140</guid>
		<description><![CDATA[No último fim de semana (18 e 19 de outubro) houve em São Paulo o CONAPHP (www.conaphp.com.br), um evento feito pela comunidade PHP e que rolou dentro do CONISLI na FIAP.
O evento em geral foi bom, com bom nível de palestras mas o público foi um pouco abaixo do que eu esperava.
Para mim, o ponto [...]]]></description>
			<content:encoded><![CDATA[<p>No último fim de semana (18 e 19 de outubro) houve em São Paulo o CONAPHP (www.conaphp.com.br), um evento feito pela comunidade PHP e que rolou dentro do CONISLI na FIAP.</p>
<p>O evento em geral foi bom, com bom nível de palestras mas o público foi um pouco abaixo do que eu esperava.</p>
<p>Para mim, o ponto alto foi quando estava assistindo a palestra do <a href="http://eltonminetto.net">Elton Minetto</a> (slides <a href="http://www.eltonminetto.net/apresentacao-no-conaphp.htm">aqui</a>) e &#8220;reconheci&#8221; um slide sobre o compilador JIT e o cache do opcode do PHP, um slide que fazia parte da apresentação que fiz em Recife no Encontro Pernambucano de SL, e para confirmar vi lá meu <a href="http://blog.feliperibeiro.com/2008/04/slides-da-palestra-php-para-desenvolvimento-de-aplicacoes-de-grande-porte.html">link</a> nas referências, e isso me deixou bastante honrado por ter um material meu usado como referência por um ícone como o Elton.</p>
<p>A minha palestra foi a última e falei sobre PHP RESTful Web Services, por ser a última, o título não ser apelativo para o pessoal mais iniciante e eu ser um ilustre desconhecido da comunidade PHP de São Paulo, tive apenas metade da sala cheia, mas o feedback das pessoas que assitiram a palestra foi bastante positivo e fiquei muito satisfeito.</p>
<p>Os slides da palestra seguem abaixo, e o código apresentado está disponível <a href="http://feliperibeiro.com/downloads/REST.zip">aqui</a>.</p>
<div id="__ss_681936" style="width: 425px; text-align: left;"><a style="font:14px Helvetica,Arial,Sans-serif;display:block;margin:12px 0 3px 0;text-decoration:underline;" title="PHP RESTful Web Services" href="http://www.slideshare.net/felipernb/php-restful-web-services-presentation?type=powerpoint">PHP RESTful Web Services</a><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slideshare.net/swf/ssplayer2.swf?doc=php-restful-ws-1224677129708039-8&amp;stripped_title=php-restful-web-services-presentation" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slideshare.net/swf/ssplayer2.swf?doc=php-restful-ws-1224677129708039-8&amp;stripped_title=php-restful-web-services-presentation" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="font-size: 11px; font-family: tahoma,arial; height: 26px; padding-top: 2px;">View SlideShare <a style="text-decoration:underline;" title="View PHP RESTful Web Services on SlideShare" href="http://www.slideshare.net/felipernb/php-restful-web-services-presentation?type=powerpoint">presentation</a> or <a style="text-decoration:underline;" href="http://www.slideshare.net/upload?type=powerpoint">Upload</a> your own. (tags: <a style="text-decoration:underline;" href="http://slideshare.net/tag/php">php</a> <a style="text-decoration:underline;" href="http://slideshare.net/tag/rest">rest</a>)</div>
</div>
<p>Quem tiver interesse sobre o assunto, deixo algumas referências:</p>
<ul>
<li><a href="http://www.sematopia.com/?p=153">http://www.sematopia.com/?p=153</a></li>
<li><a href="http://www.lornajane.net/posts/2008/Using-curl-and-PHP-to-talk-to-a-REST-service">http://www.lornajane.net/posts/2008/Using-curl-and-PHP-to-talk-to-a-REST-service</a></li>
<li><a href="http://www.lornajane.net/posts/2008/PHP-Rest-Server-part-1-of-3">http://www.lornajane.net/posts/2008/PHP-Rest-Server-part-1-of-3</a></li>
<li><a href="http://www.lornajane.net/posts/2008/PHP-Rest-Server-part-2-of-3">http://www.lornajane.net/posts/2008/PHP-Rest-Server-part-2-of-3</a></li>
<li><a href="http://www.lornajane.net/posts/2008/PHP-Rest-Server-part-3">http://www.lornajane.net/posts/2008/PHP-Rest-Server-part-3</a></li>
<li><a href="http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage">http://rest.blueoxen.net/cgi-bin/wiki.pl?FrontPage</a></li>
<li><a href="http://wiki.developer.mindtouch.com/REST/REST_for_the_Rest_of_Us">http://wiki.developer.mindtouch.com/REST/REST_for_the_Rest_of_Us</a></li>
<li><a href="http://www.xfront.com/REST-Web-Services.html">http://www.xfront.com/REST-Web-Services.html</a></li>
<li><a href="http://tomayko.com/writings/rest-to-my-wife">http://tomayko.com/writings/rest-to-my-wife</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/10/review-e-slides-do-conaphp.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Algoritmo de &#8220;Você quis dizer&#8221;</title>
		<link>http://blog.feliperibeiro.com/2008/10/algoritmo-de-voce-quis-dizer.html</link>
		<comments>http://blog.feliperibeiro.com/2008/10/algoritmo-de-voce-quis-dizer.html#comments</comments>
		<pubDate>Wed, 08 Oct 2008 17:09:44 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[apache]]></category>

		<category><![CDATA[desenvolvimento de software]]></category>

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

		<category><![CDATA[web 2.0]]></category>

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

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

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=126</guid>
		<description><![CDATA[Recentemente precisei implementar um sistema de correção ortográfica à la Google.
Pesquisei bastante sobre como fazer isso, e encontrei duas maneiras que explicarei agora, mas antes disso explicarei algo que é comum às duas: A criação do dicionário
Para criar o dicionário, você precisa ter uma base de palavras, que idealmente é um arquivo txt.
Você lê o [...]]]></description>
			<content:encoded><![CDATA[<p>Recentemente precisei implementar um sistema de correção ortográfica à la Google.</p>
<p>Pesquisei bastante sobre como fazer isso, e encontrei duas maneiras que explicarei agora, mas antes disso explicarei algo que é comum às duas: <strong>A criação do dicionário</strong></p>
<p>Para criar o dicionário, você precisa ter uma base de palavras, que idealmente é um arquivo txt.</p>
<p>Você lê o arquivo e cria um array onde as palavras são as chaves e as frequências com que aparecem nos textos serão os valores.</p>
<p><code><span style="color: #000000;"><span style="color: #0000bb;">&lt;?php<br />
$text </span><span style="color: #007700;">= </span><span style="color: #0000bb;">file_get_contents</span><span style="color: #007700;">(</span><span style="color: #dd0000;">&#8216;arquivo.txt&#8217;</span><span style="color: #007700;">);<br />
</span><span style="color: #0000bb;">preg_match_all</span><span style="color: #007700;">(</span><span style="color: #dd0000;">&#8220;/[a-z]+/&#8221;</span><span style="color: #007700;">,</span><span style="color: #0000bb;">strtolower</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$text</span><span style="color: #007700;">),</span><span style="color: #0000bb;">$matches</span><span style="color: #007700;">);<br />
</span><span style="color: #0000bb;">$palavras </span><span style="color: #007700;">= </span><span style="color: #0000bb;">$matches</span><span style="color: #007700;">[</span><span style="color: #0000bb;">0</span><span style="color: #007700;">];</span><span style="color: #0000bb;"><br />
$dicionario </span><span style="color: #007700;">= array();<br />
foreach(</span><span style="color: #0000bb;">$palavras </span><span style="color: #007700;">as </span><span style="color: #0000bb;">$palavra</span><span style="color: #007700;">)<br />
</span><span style="margin-left: 20px; color: #0000bb;">$dicionario</span><span style="color: #007700;">[</span><span style="color: #0000bb;">$palavra</span><span style="color: #007700;">] += </span><span style="color: #0000bb;">1</span><span style="color: #007700;">;<br />
</span><span style="color: #0000bb;">sort</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$dicionario</span><span style="color: #007700;">); </span><span style="color: #ff8000;">/* Essa ordenação será útil para otimização de performance no primeiro algoritmo */ </span><span style="color: #0000bb;">file_put_contents</span><span style="color: #007700;">(</span><span style="color: #dd0000;">&#8216;dicionario_serializado.dat&#8217;</span><span style="color: #007700;">,</span><span style="color: #0000bb;">serialize</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$dicionario</span><span style="color: #007700;">); </span><span style="color: #0000bb;"><br />
?&gt; </span></span></code></p>
<p>1 - Algoritmo de Levenshtein</p>
<p>PHP implementa nativamente o algoritmo de Levenshtein (<a href="http://php.net/levenshtein">http://php.net/levenshtein</a>), que calcula a distância de edição entre duas palavras, funcionando da seguinte forma:</p>
<ul>
<li>suponha que eu tenha duas palavras: água e mágua -  A distância de edição delas é de uma inserção de carácter</li>
<li>suponha que eu tenha as palavras: casa e caixa - A distância delas é de uma substituição (s por i) e uma inserção (x)</li>
<li>suponha que eu tenha as palavras: arrocho e arroto - A distância delas é de uma substituição e uma remoção.</li>
</ul>
<p>A função levenshtein também permite que você dê pesos diferenciados para inserção/remoção/substituição, sendo que o valor default é 1 para todas operações. Usando essa função, fica simples implementar um corretor, supondo que você tem um dicionário que já citei, você só precisa fazer:</p>
<p><code><span style="color: #000000;"><span style="color: #0000bb;">&lt;?php </span><span style="color: #007700;"><br />
function </span><span style="color: #0000bb;">voce_quis_dizer</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$palavra_procurada</span><span style="color: #007700;">) { </span><span style="color: #0000bb;"><br />
$dicionario </span><span style="color: #007700;">= </span><span style="color: #0000bb;">unserialize</span><span style="color: #0000bb;">(file_get_contents</span><span style="color: #007700;">(</span><span style="color: #dd0000;">&#8216;dicionario_serializado.dat&#8217;</span><span style="color: #007700;">)); </span><span style="color: #0000bb;">$minima_distancia </span><span style="color: #007700;">= -</span><span style="color: #0000bb;">1</span><span style="color: #007700;">; </span><span style="color: #0000bb;"><br />
$palavra_procurada </span><span style="color: #007700;">= </span><span style="color: #0000bb;">strtolower</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$palavra_procurada</span><span style="color: #007700;">);<br />
foreach(</span><span style="color: #0000bb;">$dicionario </span><span style="color: #007700;">as </span><span style="color: #0000bb;">$palavra_do_dicionario</span><span style="color: #007700;">) {<br />
if(</span><span style="color: #0000bb;">$palavra_procurada </span><span style="color: #007700;">== </span><span style="color: #0000bb;">$palavra_do_dicionario</span><span style="color: #007700;">) return </span><span style="color: #0000bb;">$palavra</span><span style="color: #007700;">;<br />
</span><span style="color: #0000bb;">$distancia </span><span style="color: #007700;">= </span><span style="color: #0000bb;">levenshtein</span><span style="color: #007700;">(</span><span style="color: #0000bb;">$palavra_procurada</span><span style="color: #007700;">,</span><span style="color: #0000bb;">$palavra_do_dicionario</span><span style="color: #007700;">);<br />
if(</span><span style="color: #0000bb;">$distancia </span><span style="color: #007700;">&lt; </span><span style="color: #0000bb;">$minima_distancia </span><span style="color: #007700;">|| </span><span style="color: #0000bb;">$minima_distancia </span><span style="color: #007700;">== -</span><span style="color: #0000bb;">1</span><span style="color: #007700;">) {<br />
</span><span style="color: #0000bb;">$minima_distancia </span><span style="color: #007700;">= </span><span style="color: #0000bb;">$distancia</span><span style="color: #007700;">;<br />
</span><span style="color: #0000bb;">$sugestao </span><span style="color: #007700;">= </span><span style="color: #0000bb;">$palavra_do_dicionario</span><span style="color: #007700;">;<br />
}<br />
}<br />
return </span><span style="color: #0000bb;">$sugestao</span><span style="color: #007700;">;<br />
}<br />
</span><span style="color: #0000bb;">?&gt;</span></span></code></p>
<p>Análise de desempenho:</p>
<p>Considerando que temos <strong>k</strong> palavras no dicionário, a palavra que desejamos procurar tem <strong>m</strong> letras e cada palavra do dicionário tem em média <strong>n</strong> letras, o algoritmo de Levenshtein tem ordem de complexidade <strong>O(m*n)</strong> onde para <strong>k</strong> comparações (no caso da palavra <strong>não</strong> existir no dicionário, já que se ela existir não teremos nenhuma comparação) teremos <strong>O(k*m*n)</strong> (<strong>k*m*n</strong> operações onde <strong>k</strong> é muito maior que <strong>m</strong> e <strong>n</strong>).</p>
<p>2 - Algoritmo de Peter Norvig</p>
<p>Toda explicação probabilística desse algorítmo está presente no site do Norvig, um cara renomado na área de inteligência artificial: <a href="http://norvig.com/spell-correct.html">http://norvig.com/spell-correct.html</a>. Mas basicamente esse algoritmo apesar de mais complicado é bem mais inteligente que o primeiro. O que ele faz é o seguinte: gera perturbações na sua palavra procurada e vê quais dessas perturbações é a mais relevante no dicionário. Evitando comparações desnecessárias, já que no primeiro algoritmo cada palavra que você colocar será comparada com todas as outras (por exemplo: se você digitar BOLA, e ela não existir no dicionário ela será comparada com palavras absurdas como: LIVRO, que obviamente não é o que você quis dizer).</p>
<p>Apesar do conceito do Norvig ser simples, o código é um pouquinho complicado. Então eu criei uma classe que implementa ele e disponibilizei sob Licença BSD no PHPClasses.org (<a href="http://www.phpclasses.org/browse/file/24605.html">http://www.phpclasses.org/browse/file/24605.html</a>) e tenho recebido elogios e feedback muito positivo de quem está usando.</p>
<p>Análise de desempenho:</p>
<p>Considerando <strong>26</strong> letras do alfabeto (depois da reforma da língua portuguesa, agora também temos 26 letras! :D) e considerando que sua palavra tem <strong>m</strong> letras, teremos mais ou menos 26*m iterações para gerar as possíveis perturbações na palavra (inserções, remoções e substituições possíveis), e para garantir um segundo nível de perturbações teremos aproximadamente <strong>26*m</strong> para cada perturbação gerada, que dá um total de aproximadamente (26*m)*(26*m) = 676 m². Agora só precisamos consultar cada uma das perturbações para vermos qual a mais relevante no dicionário. Cada consulta no dicionário é <strong>O(1)</strong> então desprezaremos na análise de performance.</p>
<p>E podemos considerar esse algoritmo como sendo mais eficiente do que o primeiro pois o tempo de execução cresce de acordo com o quadrado do tamanho da palavra (que normalmente é bem menor do que o tamanho do dicionário). Enquanto o primeiro sofre interferência do tamanho do dicionário e do tamanho médio das palavras contidas lá, então esse é bem mais inteligente e eficiente.</p>
<p>Espero ter ajudado!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/10/algoritmo-de-voce-quis-dizer.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Mais um termo para o Glossário Geek - &#8220;Ad hoc&#8221;</title>
		<link>http://blog.feliperibeiro.com/2008/09/mais-um-termo-para-o-glossario-geek-ad-hoc.html</link>
		<comments>http://blog.feliperibeiro.com/2008/09/mais-um-termo-para-o-glossario-geek-ad-hoc.html#comments</comments>
		<pubDate>Tue, 16 Sep 2008 01:01:35 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[geeky]]></category>

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

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=120</guid>
		<description><![CDATA[No ambiente acadêmico tenho encontrado essa expressão em diversos lugares como:

Implementação MVC ad hoc
Processo de desenvolvimento ad hoc
Redes ad hoc

E acho que muitas pessoas não entendem o significado desse termo, e muitas vezes é pronunciado errado.
Ad hoc indica que algo é feito de maneira empírica, sem formalismo, por exemplo:
Uma implementação de MVC ad hoc, é [...]]]></description>
			<content:encoded><![CDATA[<p>No ambiente acadêmico tenho encontrado essa expressão em diversos lugares como:</p>
<ul>
<li>Implementação MVC <em><strong>ad hoc</strong></em></li>
<li>Processo de desenvolvimento <em><strong>ad hoc</strong></em></li>
<li>Redes <strong><em>ad hoc</em></strong></li>
</ul>
<p>E acho que muitas pessoas não entendem o significado desse termo, e muitas vezes é pronunciado errado.</p>
<p><em><strong>Ad hoc</strong></em> indica que algo é feito de maneira empírica, sem formalismo, por exemplo:</p>
<p>Uma implementação de MVC <em><strong>ad hoc</strong><span style="font-style: normal;">, é uma implementação do padrão de projeto sem a utilização de nenhum framework para tal, algo &#8220;puro&#8221; feito de acordo com o seu entendimento sobre o padrão.</span></em></p>
<p>Um processo de desenvolvimento<strong> </strong><em><strong>ad hoc</strong></em> é um processo em que as coisas rolam sem nenhum formalismo bem definido, e por aí vai.</p>
<p>Algumas pessoas pronunciam esse termo como se fosse em inglês, como se fosse algo tipo &#8220;add hock&#8221;, mas o correto é da maneira como lemos em português mesmo, já que é um termo em latin, se pronuncia o A com som de A mesmo, e o H é mudo, como se fosse: adoque.</p>
<p>Esse post pode parecer inútil, mas espero que sirva para alguém que tem a dúvida do que significa e como se pronuncia, já que é fácil encontrar na literatura ou ouvir alguém falando, e também para tirar as teias de aranha do blog enquanto tomo um fôlego e arranjo uma brechinha na correria para voltar a postar.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/09/mais-um-termo-para-o-glossario-geek-ad-hoc.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Documentário - A verdadeira história da Internet: A guerra dos browsers</title>
		<link>http://blog.feliperibeiro.com/2008/09/documentario-a-verdadeira-historia-da-internet-a-guerra-dos-browsers.html</link>
		<comments>http://blog.feliperibeiro.com/2008/09/documentario-a-verdadeira-historia-da-internet-a-guerra-dos-browsers.html#comments</comments>
		<pubDate>Mon, 08 Sep 2008 03:35:15 +0000</pubDate>
		<dc:creator>Felipe Ribeiro</dc:creator>
		
		<category><![CDATA[browsers]]></category>

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

		<guid isPermaLink="false">http://blog.feliperibeiro.com/?p=111</guid>
		<description><![CDATA[O Discovery Channel vai apresentar uma série de documentários sobre a história da internet. Para nossa alegria o primeiro episódio, entitulado &#8220;A Guerra dos Browsers&#8221; foi disponibilizado oficialmente na internet:

Vale a pena assistir, é um vídeo super interessante que conta a história dos browsers, desde o Mosaic (bisavô do Firefox) até a briga judicial da [...]]]></description>
			<content:encoded><![CDATA[<p>O Discovery Channel vai apresentar uma série de documentários sobre a história da internet. Para nossa alegria o primeiro episódio, entitulado &#8220;A Guerra dos Browsers&#8221; foi disponibilizado oficialmente na internet:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="460" height="390" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="name" value="flashObj" /><param name="bgcolor" value="#FFFFFF" /><param name="flashvars" value="videoId=1753200785&amp;playerId=1417402673&amp;viewerSecureGatewayURL=https://console.brightcove.com/services/amfgateway&amp;servicesURL=http://services.brightcove.com/services&amp;cdnURL=http://admin.brightcove.com&amp;domain=embed&amp;autoStart=false&amp;" /><param name="src" value="http://services.brightcove.com/services/viewer/federated_f8/1417402673" /><embed type="application/x-shockwave-flash" width="460" height="390" src="http://services.brightcove.com/services/viewer/federated_f8/1417402673" flashvars="videoId=1753200785&amp;playerId=1417402673&amp;viewerSecureGatewayURL=https://console.brightcove.com/services/amfgateway&amp;servicesURL=http://services.brightcove.com/services&amp;cdnURL=http://admin.brightcove.com&amp;domain=embed&amp;autoStart=false&amp;" bgcolor="#FFFFFF" name="flashObj"></embed></object></p>
<p>Vale a pena assistir, é um vídeo super interessante que conta a história dos browsers, desde o Mosaic (bisavô do Firefox) até a briga judicial da infame Microsoft com seu ainda mais infame Internet Explorer e o Netscape (avô do Firefox). O vídeo tem cerca de 43 minutos, mas é muito interessante, recomendadíssimo! E tenho certeza que depois dele, se você ainda usa IEca, vai deixar de usar.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.feliperibeiro.com/2008/09/documentario-a-verdadeira-historia-da-internet-a-guerra-dos-browsers.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
