<?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>Jonnas Fonini</title>
	<atom:link href="http://www.fonini.net/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fonini.net/blog</link>
	<description></description>
	<lastBuildDate>Wed, 15 May 2013 17:59:43 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Snippets úteis do Zend Framework</title>
		<link>http://www.fonini.net/blog/snippets-uteis-do-zend-framework/</link>
		<comments>http://www.fonini.net/blog/snippets-uteis-do-zend-framework/#comments</comments>
		<pubDate>Thu, 09 May 2013 13:30:50 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Zend Framework]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=340</guid>
		<description><![CDATA[Compartilho aqui alguns snippets e comandos úteis do Zend Framework, para referência futura e quem sabe ajudar alguém que precise. Retornar o código de resposta 404 (Not found). Redirecionar para URL com âncora (sharp/cerquilha/jogo da velha) Trocar o layout no &#8230; <a href="http://www.fonini.net/blog/snippets-uteis-do-zend-framework/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Compartilho aqui alguns snippets e comandos úteis do Zend Framework, para referência futura e quem sabe ajudar alguém que precise.<br />
<br/></p>
<h4>Retornar o código de resposta 404 (Not found).</h4>
<pre class="brush: php; title: ; notranslate"> $this-&gt;_response-&gt;clearBody()-&gt;clearHeaders()-&gt;setHttpResponseCode(404)-&gt;sendResponse(); </pre>
<p><br/></p>
<h4>Redirecionar para URL com âncora (sharp/cerquilha/jogo da velha)</h4>
<pre class="brush: php; title: ; notranslate"> $opt = array('module' =&gt; 'admin', 'controller' =&gt; 'galeria', 'action' =&gt; 'editar', 'id' =&gt; 1); $url = $this-&gt;_helper-&gt;getHelper('Url')-&gt;url($opt); $url .= &quot;#descricao&quot;; $this-&gt;_helper-&gt;redirector-&gt;gotoUrl($url); </pre>
<p><br/></p>
<h4>Trocar o layout no controller</h4>
<pre class="brush: php; title: ; notranslate"> $this-&gt;_helper-&gt;layout-&gt;setLayout('servicos'); </pre>
<p><br/></p>
<h4>Timestamp no formato de banco de dados</h4>
<pre class="brush: php; title: ; notranslate"> Zend_Date::now()-&gt;toString('yyyy-MM-dd HH:mm:ss'); </pre>
<p><br/></p>
<h4>Desabilitar layout</h4>
<pre class="brush: php; title: ; notranslate"> $this-&gt;_helper-&gt;layout()-&gt;disableLayout(); </pre>
<p><br/></p>
<h4>Desabilitar renderização da view</h4>
<pre class="brush: php; title: ; notranslate">$this-&gt;_helper-&gt;viewRenderer-&gt;setNoRender(true);</pre>
<p><br/></p>
<h4>Debugar consultas no banco de dados</h4>
<pre class="brush: php; title: ; notranslate"> $db = Zend_Db_Table::getDefaultAdapter(); $profiler = $db-&gt;getProfiler()-&gt;setEnabled(true); print_r($profiler-&gt;getLastQueryProfile()); </pre>
<p><br/></p>
<h4>Dados do usuário logado (caso esteja usando Zend_Auth)</h4>
<pre class="brush: php; title: ; notranslate">Zend_Auth::getInstance()-&gt;getIdentity();</pre>
<p><br/></p>
<h4>Utilizando transações: </h4>
<pre class="brush: php; title: ; notranslate">$db = Zend_Db_Table::getDefaultAdapter();

try{
	$db-&gt;beginTransaction();
	// query
	$db-&gt;commit();
}
catch(Exception $e){
	$db-&gt;rollBack();
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/snippets-uteis-do-zend-framework/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gerar número sequencial em query do PostgreSQL</title>
		<link>http://www.fonini.net/blog/gerar-numero-sequencial-em-query-do-postgresql/</link>
		<comments>http://www.fonini.net/blog/gerar-numero-sequencial-em-query-do-postgresql/#comments</comments>
		<pubDate>Thu, 07 Mar 2013 20:20:08 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=449</guid>
		<description><![CDATA[Dica rápida para quem precisa gerar um número sequencial para cada registro retornado por uma query no PostgreSQL: A sequência retornada começa em 1. Se quiser que ela comece em 0, basta adaptar a consulta: Caso você utilize uma cláusula &#8230; <a href="http://www.fonini.net/blog/gerar-numero-sequencial-em-query-do-postgresql/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Dica rápida para quem precisa gerar um número sequencial para cada registro retornado por uma query no PostgreSQL:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT row_number() OVER (PARTITION by 0) as _seq, id, FROM pessoa
</pre>
<p>A sequência retornada começa em 1. Se quiser que ela comece em 0, basta adaptar a consulta:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT row_number() OVER (PARTITION by 0) - 1 as _seq, id, nome FROM pessoa
</pre>
<p>Caso você utilize uma cláusula ORDER BY, os números gerados provavelmente estarão fora de ordem. Para corrigir este problema, basta repetir a cláusula ORDER BY dentro da função OVER, ficando como no exemplo abaixo:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT row_number() OVER (PARTITION by 0 ORDER BY data) - 1 as _seq, 
id, nome FROM pessoa 
ORDER BY data
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/gerar-numero-sequencial-em-query-do-postgresql/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Convertendo varchar para time without time zone no PostgreSQL</title>
		<link>http://www.fonini.net/blog/convertendo-varchar-para-time-without-time-zone-no-postgresql/</link>
		<comments>http://www.fonini.net/blog/convertendo-varchar-para-time-without-time-zone-no-postgresql/#comments</comments>
		<pubDate>Mon, 26 Mar 2012 17:56:51 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[PostgreSQL]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=433</guid>
		<description><![CDATA[Dica rápida pra quem está precisando converter um valor em varchar para time without time zone no PostgreSQL. Usando a função to_timestamp(valor, formato), o valor retornado é um timestamp with time zone. Porém, basta adicionar ao final da chamada da &#8230; <a href="http://www.fonini.net/blog/convertendo-varchar-para-time-without-time-zone-no-postgresql/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
	Dica rápida pra quem está precisando converter um valor em varchar para time without time zone no PostgreSQL.
</p>
<p>
	Usando a função to_timestamp(valor, formato), o valor retornado é um <strong>timestamp with time zone</strong>.
</p>
<p>
	Porém, basta adicionar ao final da chamada da função o tipo do retorno desejado:
</p>
</p>
<pre class="brush: sql; title: ; notranslate">
to_timestamp('23:59:59', 'HH24:MI:SS')::time without time zone
</pre>
</p>
<p>
	Tive um problema com PHP, usando PDO com PostgreSQL e a função overlaps(). Precisava passar um valor time para a função e funcionou dessa maneira.
</p>
<p>
	Espero ajudar alguém.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/convertendo-varchar-para-time-without-time-zone-no-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Restringindo caracteres digitados no EditText do Android</title>
		<link>http://www.fonini.net/blog/restringindo-caracteres-digitados-no-edittext-do-android/</link>
		<comments>http://www.fonini.net/blog/restringindo-caracteres-digitados-no-edittext-do-android/#comments</comments>
		<pubDate>Fri, 02 Mar 2012 13:51:24 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=420</guid>
		<description><![CDATA[Desenvolvendo em Android, temos alguns casos em que precisamos restringir os caracteres que são permitidos em campos como o EditText. Um exemplo, é um campo que aceite valores como 1,80 e 1.80. No caso, se a restrição fosse somente números &#8230; <a href="http://www.fonini.net/blog/restringindo-caracteres-digitados-no-edittext-do-android/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
	Desenvolvendo em Android, temos alguns casos em que precisamos restringir os caracteres que são permitidos em campos como o EditText.
</p>
<p>
	Um exemplo, é um campo que aceite valores como <strong>1,80</strong> e <strong>1.80</strong>. No caso, se a restrição fosse somente números com . (ponto) como separador decimal, bastaria definir o <strong>android:inputType</strong> como <strong>numberDecimal</strong>. Porém, número com , (vírgula) como separador não iriam funcionar.
</p>
<p>
	Para tarefas como essa, o atributo <strong>android:digits</strong> está aí para salvar a pátria. Basta definir nele quais dígitos serão permitidos naquele EditText e o Android cuida do resto.
</p>
<p>
	Exemplo:
</p>
<p>
	<strong>Permitir somente números, tanto com . como , como separadores decimais:</strong>
</p>
</p>
<pre class="brush: xml; title: ; notranslate">
&lt;EditText android:digits=&quot;1234567890.,&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; /&gt;
</pre>
</p>
<p>
	Fácil, não?
</p>
<p>
	Essa solução também é util para ser usada em conjunto com o android:inputType=&#8221;numberDecimal&#8221;. Nesse caso, é apresentado o teclado numérico, permitindo que vírgulas também sejam incluídas.
</p>
<p>
	Exemplo:
</p>
</p>
<pre class="brush: xml; title: ; notranslate">
&lt;EditText android:digits=&quot;1234567890.,&quot; android:inputType=&quot;numberDecimal&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; /&gt;
</pre>
</p>
<p>
	&nbsp;
</p>
<h3>
	Outros exemplos<br />
</h3>
<p>
	<strong>Números hexadecimais:</strong>
</p>
</p>
<pre class="brush: xml; title: ; notranslate">
&lt;EditText android:digits=&quot;abcdef1234567890&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; /&gt;
</pre>
</p>
<p>
	<strong>Somente números pares:</strong>
</p>
</p>
<pre class="brush: xml; title: ; notranslate">
&lt;EditText android:digits=02468&quot; android:inputType=&quot;number&quot; android:layout_width=&quot;wrap_content&quot; android:layout_height=&quot;wrap_content&quot; /&gt;
</pre>
</p>
<p>
	&nbsp;
</p>
<p>
	Abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/restringindo-caracteres-digitados-no-edittext-do-android/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Debugando seu aplicativo Android no tablet Coby Kyros Mid8024</title>
		<link>http://www.fonini.net/blog/debugando-seu-aplicativo-android-no-tablet-coby-kyros-mid8024/</link>
		<comments>http://www.fonini.net/blog/debugando-seu-aplicativo-android-no-tablet-coby-kyros-mid8024/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 16:53:20 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Driver]]></category>
		<category><![CDATA[Xing Ling]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=411</guid>
		<description><![CDATA[Hoje precisei instalar uma app Android que desenvolvi no tablet de um cliente. Conectei o bicho no USB do computador e nada de reconhecer. Olhei no Gerenciador de Dispositivos do Windows 7 (infelizmente preciso trabalhar no maldito) e vi que &#8230; <a href="http://www.fonini.net/blog/debugando-seu-aplicativo-android-no-tablet-coby-kyros-mid8024/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
	Hoje precisei instalar uma app Android que desenvolvi no tablet de um cliente. Conectei o bicho no USB do computador e nada de reconhecer. Olhei no Gerenciador de Dispositivos do Windows 7 (infelizmente preciso trabalhar no maldito) e vi que existia um dispositivo não reconhecido, o <strong>S5P OTG-USB </strong>.
</p>
<p>
	Após alguma procura, localizei o driver necessário, esse <a href="http://www.driveridentifier.com/scan/driver_file_detail.php?inf_file_id=510504&amp;md5=830fc6ecaf4549aac2fe3a52df8745d4&amp;scanid=1E91495F3AD149598DF2EFE444EC31B1&amp;item_id=278631742&amp;hardware_id=USBVID_18D1%26PID_4E22%26MI_01">aqui</a>. Agora, basta extrair os arquivos para alguma pasta,&nbsp; ir novamente no Gerenciador de Dispositivos, clicar com o botão direito no S5P OTG-USB, clicar em Atualizar driver (ou instalar driver, se necessário) e localizar a pasta dos drivers.
</p>
<p>
	Pronto. Para testar se funcionou, execute comando: <strong>adb devices</strong> e veja se seu dispositivo foi reconhecido. No meu caso, ele foi reconhecido como <strong>MID_Serials device</strong>.
</p>
<p>
	Agora basta debugar seu aplicativo.
</p>
<p>
	No no meu caso, eu fazia o download da app, começava a instalação, mas aparecia a mensagem: &#8220;<strong>O aplicativo não foi instalado</strong>&#8220;. Fiz o processo para debugar o aplicativo e descobri que o tablet não tinha a lib do Google Maps. O erro era esse: INSTALL_FAILED_MISSING_SHARED_LIBRARY.
</p>
<p>
	O processo de debug direto no dispositivo me fez perceber o problema na hora. Se não tivesse debugado, estaria até agora tentando entender o erro. Fica a dica.
</p>
<p>
	<a href="http://www.driveridentifier.com/scan/driver_file_detail.php?inf_file_id=510504&amp;md5=830fc6ecaf4549aac2fe3a52df8745d4&amp;scanid=1E91495F3AD149598DF2EFE444EC31B1&amp;item_id=278631742&amp;hardware_id=USBVID_18D1%26PID_4E22%26MI_01">Download do driver</a>
</p>
<p>
	<a href="http://dl.dropbox.com/u/9937691/android_usb_driver.zip">Link alternativo</a>
</p>
<p>
	Grande abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/debugando-seu-aplicativo-android-no-tablet-coby-kyros-mid8024/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Convertendo de UTF-8 para ISO-8859-1 em Java: A solução definitiva</title>
		<link>http://www.fonini.net/blog/convertendo-de-utf-8-para-iso-8859-1-em-java-a-solucao-definitiva/</link>
		<comments>http://www.fonini.net/blog/convertendo-de-utf-8-para-iso-8859-1-em-java-a-solucao-definitiva/#comments</comments>
		<pubDate>Wed, 29 Feb 2012 17:54:19 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Charset]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=404</guid>
		<description><![CDATA[Recentemente enfrentei problemas em um aplicativo Android que desenvolvi, o qual se comunica com o banco de dados de um dos sistemas da empresa, codificado em ISO-8859-1 (Firebird) através de um web service. Os dados eram gravados de forma errada, &#8230; <a href="http://www.fonini.net/blog/convertendo-de-utf-8-para-iso-8859-1-em-java-a-solucao-definitiva/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
	Recentemente enfrentei problemas em um aplicativo Android que desenvolvi, o qual se comunica com o banco de dados de um dos sistemas da empresa, codificado em ISO-8859-1 (Firebird) através de um web service.
</p>
<p>
	Os dados eram gravados de forma errada, muitas vezes truncavam e as vezes apareciam caracteres estranhos.
</p>
<p>
	Depois de algumas tentativas, cheguei até a seguinte solução:
</p>
<p><br/><br/><br/><br/><br/></p>
<pre class="brush: java; title: ; notranslate">
public static String convertUTF8toISO(String str) {
	String ret = null;
	try {
		ret = new String(str.getBytes(&quot;ISO-8859-1&quot;), &quot;UTF-8&quot;);
	} 
	catch (java.io.UnsupportedEncodingException e) {
		return null;
	}
	return ret;
}
</pre>
</p>
<p>
	Adicione o método acima à sua classe de utilidades e acabe com os seus problemas.
</p>
<p>
	Abraço.
</p>
<p>
	&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/convertendo-de-utf-8-para-iso-8859-1-em-java-a-solucao-definitiva/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Acessando o localhost a partir do emulador do Android</title>
		<link>http://www.fonini.net/blog/acessando-o-localhost-a-partir-do-emulador-do-android/</link>
		<comments>http://www.fonini.net/blog/acessando-o-localhost-a-partir-do-emulador-do-android/#comments</comments>
		<pubDate>Fri, 24 Feb 2012 11:06:41 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=394</guid>
		<description><![CDATA[Um requisito muito comum de um aplicativo desenvolvido para a plataforma Android é que o mesmo acesse um web service para troca de informações. No momento do desenvolvimento do aplicativo, geralmente o web service fica na mesma máquina em que &#8230; <a href="http://www.fonini.net/blog/acessando-o-localhost-a-partir-do-emulador-do-android/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
	Um requisito muito comum de um aplicativo desenvolvido para a plataforma Android é que o mesmo acesse um web service para troca de informações. No momento do desenvolvimento do aplicativo, geralmente o web service fica na mesma máquina em que se encontra o emulador.
</p>
<p>
	Como faço pra acessar o localhost da máquina através do emulador? Usando &#8220;localhost&#8221; na string de conexão? Não funciona.
</p>
<p>
	Uso o IP da minha máquina para conectar? Pode até funcionar, mas e se você estiver desconectado?
</p>
<p>
	Neste caso, basta usar o IP mágico, <strong>10.0.2.2</strong>. Através deste endereço, o emulador Android saberá que deve acessar o localhost da sua máquina, independente da configuração da sua rede e mesmo que você estiver desconectado.
</p>
<p>
	Tente você mesmo. Com seu servidor web iniciado, acesse o endereço através do browser do emulador Android.
</p>
<p>
	Saudações!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/acessando-o-localhost-a-partir-do-emulador-do-android/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Tutorial de Instalação e Configuração do Doctrine 2.2</title>
		<link>http://www.fonini.net/blog/tutorial-doctrine-de-instalacao-e-configuracao-do-2-2/</link>
		<comments>http://www.fonini.net/blog/tutorial-doctrine-de-instalacao-e-configuracao-do-2-2/#comments</comments>
		<pubDate>Thu, 23 Feb 2012 01:46:33 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Doctrine]]></category>
		<category><![CDATA[ORM]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=346</guid>
		<description><![CDATA[Ol&#225;! Esta &#233; a primeira vez que arrumo tempo para testar a vers&#227;o 2 deste famoso ORM para PHP, o Doctrine. Criei este tutorial para servir como refer&#234;ncia futura e tamb&#233;m para eventualmente auxiliar algu&#233;m que esteja estudando. Vale lembrar &#8230; <a href="http://www.fonini.net/blog/tutorial-doctrine-de-instalacao-e-configuracao-do-2-2/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Ol&aacute;! Esta &eacute; a primeira vez que arrumo tempo para testar a vers&atilde;o 2 deste famoso ORM para PHP, o Doctrine. Criei este tutorial para servir como refer&ecirc;ncia futura e tamb&eacute;m para eventualmente auxiliar algu&eacute;m que esteja estudando. Vale lembrar que voc&ecirc; precisa ter o PHP 5.3.0 ou superior instalado na m&aacute;quina devido aos namespaces utilizados no Doctrine 2.</p>
<p>&nbsp;</p>
<h3>Download e Instala&ccedil;&atilde;o</h3>
<p><a href="http://www.doctrine-project.org/downloads/DoctrineORM-2.2.0-full.tar.gz" rel="nofollow">Baixe a &uacute;ltima vers&atilde;o</a> (no momento em que escrevo &eacute; a 2.2): Crie uma pasta no seu servidor e extraia o conte&uacute;do do arquivo rec&eacute;m baixado para dentro dela. Sua estrutura dever&aacute; ficar mais ou menos assim:</p>
<pre>sua_pasta
|-- bin
|-- Doctrine
|-- entities</pre>
<p>Logo ap&oacute;s, crie na raiz um arquivo chamado &quot;bootstrap.php&quot;. Este arquivo ir&aacute; conter a configura&ccedil;&atilde;o b&aacute;sica do Doctrine 2, bem como fornecer&aacute; uma inst&acirc;ncia do Entity Manager. Opa, Entity Manager? &Eacute; meu amigo, dessa vez a semelhan&ccedil;a com o Hibernate est&aacute; maior ainda. As entidades tem at&eacute; anota&ccedil;&otilde;es! Claro que voc&ecirc; pode definir as entidades com XML (argh) e YAML. Mas pelo menos pra mim, nada como definir como classes PHP! Crie tamb&eacute;m um banco de dados para testar o Doctrine 2.
<pre class="brush: php; title: ; notranslate"> 
// bootstrap.php 

use DoctrineORMToolsSetup; 
require_once &quot;entities/Cidade.php&quot;; 
require_once &quot;entities/Pessoa.php&quot;; 

require_once &quot;Doctrine/ORM/Tools/Setup.php&quot;; 

Setup::registerAutoloadPEAR(); 

$debug = true; 
$config = Setup::createAnnotationMetadataConfiguration(array(__DIR__.&quot;/entities&quot;), $debug); 

// Configuração de acesso ao banco de dados 
$conn = array( 
    'driver' =&gt; 'pdo_mysql', 
    'user' =&gt; 'usuario', 
    'password' =&gt; 'senha', 
    'dbname' =&gt; 'doctrine2_test' 
); 

// Obtendo uma instância do Entity Manager 
$entityManager = DoctrineORMEntityManager::create($conn, $config); </pre>
</p>
<p>&nbsp;</p>
<h3>Definindo as entidades</h3>
<p>Agora que voc&ecirc; j&aacute; configurou o bootstrap, vamos criar as entidades (classes) que ser&atilde;o usadas para a persist&ecirc;ncia no banco de dados. Na pasta &quot;entities&quot;, criada anteriormente, crie os arquivos &quot;Cidade.php&quot; e &quot;Pessoa.php&quot; com o conte&uacute;do abaixo: </p>
<pre class="brush: php; title: ; notranslate"> 
// entities/Cidade.php 

use DoctrineCommonCollectionsArrayCollection; 

/** * @Entity @Table(name=&quot;cidade&quot;) */ 
class Cidade { 
    /** @Id @Column(type=&quot;integer&quot;) @GeneratedValue */ 
    protected $id; 

    /** @Column(type=&quot;string&quot;) */ 
    protected $nome; 

    /** @Column(type=&quot;string&quot;) */ 
    protected $uf; 

    /** * @OneToMany(targetEntity=&quot;Pessoa&quot;, mappedBy=&quot;cidade&quot;) * 
    @var Pessoa[] */ 
    protected $habitantesCidade = null; 

    public function __construct() { 
        $this-&gt;habitantesCidade = new ArrayCollection(); 
    } 

    public function getId() { 
        return $this-&gt;id; 
    } 

    public function getNome() { 
        return $this-&gt;nome; 
    } 

    public function setNome($nome) { 
        $this-&gt;nome = $nome; 
    } 

    public function getUf() { 
        return $this-&gt;uf; 
    } 

    public function setUf($uf) { 
        $this-&gt;uf = $uf; 
    } 

    public function adicionarHabitante($pessoa) { 
        $this-&gt;habitantesCidade[] = $pessoa; 
    } 
}
</pre>
<p> &nbsp;<br />
<br/><br/></p>
<pre class="brush: php; title: ; notranslate"> 
// entities/Pessoa.php 

/** * @Entity @Table(name=&quot;pessoa&quot;) */ 
class Pessoa { 
    /** @Id @Column(type=&quot;integer&quot;) @GeneratedValue */ 
    protected $id; 

    /** @Column(type=&quot;string&quot;) */ 
    protected $nome; 

    /** @Column(type=&quot;datetime&quot;) */ 
    protected $dataHoraCadastro; 

    /** * @ManyToOne(targetEntity=&quot;Cidade&quot;, inversedBy=&quot;habitantesCidade&quot;) */ 
    protected $cidade; 

    public function getId() { 
        return $this-&gt;id; 
    } 

    public function getNome() { 
        return $this-&gt;nome; 
    } 

    public function setNome($nome) { 
        $this-&gt;nome = $nome; 
    } 

    public function getDataHoraCadastro() { 
        return $this-&gt;dataHoraCadastro; 
    } 

    public function setDataHoraCadastro(DateTime $dataHoraCadastro) { 
        $this-&gt;dataHoraCadastro = $dataHoraCadastro; 
    } 

    public function getCidade() { 
        return $this-&gt;cidade; 
    } 

    public function setCidade($cidade) { 
        $this-&gt;cidade = $cidade; 
    } 
}
</pre>
</p>
<p>&nbsp;</p>
<h3>Cria&ccedil;&atilde;o das tabelas</h3>
<p>A cria&ccedil;&atilde;o das tabelas no banco de dados ser&aacute; feita atrav&eacute;s da linha de comando. Caso n&atilde;o queira usar a linha de comando, o arquivo com os comandos SQL se encontra para download no final do post, juntamente com o projeto completo.</p>
<p>&nbsp;</p>
<h3>Utilizando a linha de comando</h3>
<p>Se voc&ecirc; deseja usar a linha de comando do Doctrine 2, fa&ccedil;a uma pequena altera&ccedil;&atilde;o no arquivo bin/doctrine, adicionando a seguinte linha antes do include: <br/></p>
<pre class="brush: php; title: ; notranslate"> set_include_path(get_include_path() . PATH_SEPARATOR . '../'); </pre>
<p>Crie na raiz um arquivo chamado config-cli.php, que ir&aacute; conter a configura&ccedil;&atilde;o para rodar o Doctrine Tool atrav&eacute;s do terminal do Linux (ou prompt do Windows).</p>
<pre class="brush: php; title: ; notranslate"> 
// config-cli.php 

require_once &quot;bootstrap.php&quot;; 

$helperSet = new SymfonyComponentConsoleHelperHelperSet(array( 'em' =&gt; new DoctrineORMToolsConsoleHelperEntityManagerHelper($entityManager) )); 
</pre>
<p>Agora voc&ecirc; j&aacute; pode acessar a pasta &quot;bin&quot; atrav&eacute;s do terminal e gerar o SQL necess&aacute;rio para criar as tabelas usadas no exemplo. Para isto, basta entrar na pasta &quot;bin&quot; e rodar o comando:</p>

<div class="wp-terminal">fonini@valhalla:$ ./doctrine orm:schema-tool:create --dump-sql<br/></div>

<p>Ou se preferir, voc&ecirc; pode deixar o Doctrine conectar ao banco de dados e criar as tabelas para voc&ecirc;. Para isto, basta remover o trecho &quot;&#8211;dump-sql&quot; do comando. Criado o banco de dados, vamos testar a persist&ecirc;ncia de uma entidade (vulgo insert). Crie um arquivo com o nome de sua prefer&ecirc;ncia na ra&iacute;z, com o seguinte conte&uacute;do: </p>
<pre class="brush: php; title: ; notranslate"> 
require &quot;bootstrap.php&quot;; 

$cidade = new Cidade(); 
$cidade-&gt;setNome('Marau'); 
$cidade-&gt;setUf('RS'); 

$entityManager-&gt;persist($cidade); 
$entityManager-&gt;flush(); 

echo &quot;Cidade criada com o ID &quot;.$cidade-&gt;getId().&quot;n&quot;; 
</pre>
<p>Rode o arquivo. Legal, n&atilde;o? Se n&atilde;o houve nenhum erro, d&ecirc; uma olhada no banco de dados, que o seu registro estar&aacute; l&aacute;. Caso houve algum erro, debugue at&eacute; a morte para encontrar o maldito e deixar funcionando. Veja agora um exemplo de persist&ecirc;ncia de um objeto da classe Pessoa com um objeto da classe Cidade associado: </p>
<pre class="brush: php; title: ; notranslate"> 
require &quot;bootstrap.php&quot;; 

$cidade = new Cidade(); 
$cidade-&gt;setNome('Marau'); 
$cidade-&gt;setUf('RS'); 

$pessoa = new Pessoa(); 
$pessoa-&gt;setNome('Jonnas Fonini'); 
$pessoa-&gt;setDataHoraCadastro(new DateTime(&quot;now&quot;)); 
$pessoa-&gt;setCidade($cidade); 

$entityManager-&gt;persist($cidade); 
$entityManager-&gt;persist($pessoa); 
$entityManager-&gt;flush(); 

echo &quot;Pessoa criada com o ID &quot;.$pessoa-&gt;getId().&quot; e associada com a Cidade &quot;.$cidade-&gt;getId(); 
</pre>
<p>&nbsp;</p>
<h3>Localizando uma entidade pelo ID</h3>
<pre class="brush: php; title: ; notranslate"> 
require &quot;bootstrap.php&quot;; 

$pessoa = $entityManager-&gt;find(&quot;Pessoa&quot;, 1); 
print 'Nome: ' . $pessoa-&gt;getNome() . ' '; 
print 'Cidade: ' . $pessoa-&gt;getCidade()-&gt;getNome(); 
</pre>
<p>Outros exemplos, como listagem, atualiza&ccedil;&atilde;o e exclus&atilde;o voc&ecirc; encontra no arquivo dispon&iacute;vel no final do post.</p>
<p>&nbsp;</p>
<h3>Conclus&atilde;o</h3>
<p>Apesar de ser a primeira vez que uso o Doctrine 2, posso dizer que est&aacute; demais! Est&aacute; bem mais organizado que a primeira vers&atilde;o, sem contar que as anota&ccedil;&otilde;es facilitam muito o mapeamento do banco. Pra quem n&atilde;o gosta, pode usar XML e YAML. O bootstrap tamb&eacute;m est&aacute; mais limpo e exige bem menos configura&ccedil;&atilde;o.</p>
<p>&nbsp;</p>
<h3>Download</h3>
<p><a href="http://www.fonini.net/labs/doctrine2.zip">Baixe aqui</a> os arquivos usados no exemplo. Grande abra&ccedil;o a todos e at&eacute; a pr&oacute;xima.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/tutorial-doctrine-de-instalacao-e-configuracao-do-2-2/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>&#8220;Doritos&#8221; na URL de logout do Google</title>
		<link>http://www.fonini.net/blog/doritos-na-url-de-logout-do-google/</link>
		<comments>http://www.fonini.net/blog/doritos-na-url-de-logout-do-google/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 15:38:31 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Geral]]></category>
		<category><![CDATA[Easter Egg]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=318</guid>
		<description><![CDATA[Há algum tempo atrás pensei estar vendo coisas. Uma dessas coisas me pareceu ser a palavra &#8220;doritos&#8221; na URL de logout do Google. Mas o logout acontece tão rápido que nunca consegui tirar um print pra confirmar. E outra, não &#8230; <a href="http://www.fonini.net/blog/doritos-na-url-de-logout-do-google/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>Há algum tempo atrás pensei estar vendo coisas. Uma dessas coisas me pareceu ser a palavra &#8220;doritos&#8221; na URL de logout do Google. Mas o logout acontece tão rápido que nunca consegui tirar um print pra confirmar. E outra, não é sempre que aparece. Hoje pela manhã consegui! Veja na imagem abaixo:</p>
<p><img class="alignnone  wp-image-319" src="wp-content/imagens/google-doritos-url-get-param.png" alt="FINALMENTE CAPTUREI O PRINT!" width="813" height="27" /></p>
<p>Repito: não é sempre que aparece.</p>
<p>Segundo o Bruno Bemfica (<a href="http://twitter.com/ubuntroll">@ubuntroll</a>), é  porque o Google não gosta de cookies e prefere usar Doritos em suas páginas.</p>
<p>Abraço e bom final de ano!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/doritos-na-url-de-logout-do-google/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>HTTPRequest, classe PHP para retornar conteúdo remoto em servidores sem cURL</title>
		<link>http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl/</link>
		<comments>http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 19:49:14 +0000</pubDate>
		<dc:creator>fonini</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://www.fonini.net/blog/?p=130</guid>
		<description><![CDATA[Ataquei de freelancer recentemente, tendo que desenvolver um site. O cliente já havia contratado um popular provedor de acesso à internet da região para hospedar o site. Nada além do apocalipse poderia acontecer. Vou explicar. Os provedores da região na &#8230; <a href="http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
				<content:encoded><![CDATA[<p>
	Ataquei de freelancer recentemente, tendo que desenvolver um site. O cliente já havia contratado um popular provedor de acesso à internet da região para hospedar o site. Nada além do apocalipse poderia acontecer. Vou explicar. Os provedores da região na qual resido deveriam se preocupar um pouco mais em oferecer acesso de qualidade e deixar o ramo de hospedagem de aplicações web para quem realmente entende. O maldito servidor estava simplesmente &#8220;pelado&#8221;, extensões importantes faltando e metade dos recursos úteis desabilitados.</p>
<p>
	Aonde já se viu um servidor sem cURL? Pois é, ainda fiz uma última tentativa para obter conteúdo remoto (previsão do tempo, infelizmente ainda é uma triste realidade por aqui o cliente exigir isso no site) usando file_get_contents(), mas adivinhem: allow_url_fopen desabilitado.</p>
<p>
	Felizmente existem os sockets! Dei uma fuçada na net, juntei alguns snippets e criei uma classe para facilitar o serviço. Podem conferir o código e outras informações no meu <a href="http://www.github.com/fonini/HTTPRequest" rel="externo nofollow">Github</a>.</p>
<p>
	Grande abraço!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fonini.net/blog/httprequest-classe-php-para-retornar-conteudo-remoto-em-servidores-sem-curl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
