sábado, 31 de dezembro de 2011

Documento XHTML 1.0 mínimo

Seus sites seguem os padrões web? Um jeito rápido de você saber é usando o serviço de validação do W3C (World Wide Web Consortium), o Markup Validation Service. Nele podemos validar documentos HTML e XHTML. Mas porque ter o trabalho a mais de manter os meus sites dentro dos padrões web? Bom, além de torná-lo um cidadão modelo na internet, sites que seguem os padrões web são melhores vistos por engines de busca como a google o que melhora a posição e visibilidade de seus sites. O uso de padrões também melhora a acessibilidade dos sites para pessoas com deficiências, isso é especialmente importante para sites governamentais. Outra vantagem é que com os padrões é mais fácil evitar problemas de incompatibilidades entre diferentes browsers, hoje um site tem que ser exibido corretamente em no mínimo três browsers diferentes: Firefox, Chrome e Internet Explorer. Sem contar os browsers de dispositivos móveis que são um boa parte dos acessos hoje em dia.

Eu geralmente uso XHTML 1.0 nos meus sites, e toda página servida deve uma estrutura mínima para estar dentro dos padrões. Aqui vai o exemplo:



Este documento usa o DOCTTYPE XHTML 1.0 Strict, que é bem rígido com a estrutura do documento. O DOCTYPE define os DTD (Document Type Definitions) usados para validar a sintaxe e gramática da marcação XHTML. Existem várias regras para escrever um documento xhtml válido como todas as tags tem que ser escritas com letras minúsculas, todas as tags de abertura devem ter a tag de fechamento correspondente, os atributos das tags também devem ser escritos com letras minúsculas etc.

O DOCTYPE Strict é mais indicado para páginas onde a marcação html e a apresentação são totalmente separadas através do uso de CSS. Um DOCTYPE mais flexível é o Transitional, que permite o uso de elementos em desuso, ou quando o documento mistura marcação e regras de apresentação. Neste caso o exemplo seria:



Muitas das informações neste post foram obtidas no excelente livro "Construindo sites com CSS e (X)HTML" de Maurício Samy Silva.

Quer você use XHTML ou HTML eu acho muito importante seguirmos os padrões web, desta forma sempre estaremos tornando a web um lugar melhor.

domingo, 18 de dezembro de 2011

Como escrever javascript com PHP?

Quem já tem alguma experiência com desenvolvimento web já deve ter passado pela experiência de escrever código javascript usando código PHP. A técnica é bem interessante e poderosa, pois você está gerando código javascript dinamicamente usando PHP que também é uma linguagem dinâmica, Batman e Robin ficariam orgulhosos.

Aqui vai um exemplo: Você tem um site bastante visitado e que usa bastante ajax para evitar recarregar toda a página para cada ação do usuário. Mas e que tal você economizar até nas chamadas ajax? Supondo aquela situação básica onde o usuário do site escolhe uma opção em um select e algum lugar da página é recarregado automaticamente de acordo com a opção escolhida. Supondo ainda que as informações envolvidas não mudem com muita frequência, vamos fazer com todas as informações já estejam na página permitindo o código javascript carregar as informações na página sem uma requisição ajax.



O código simplesmente preenche o input "sentimento_cor" de acordo com a cor escolhida no select. Como vocês podem ver estou preenchendo o array javascript "sentimentos_cores" com os valores vindos do array PHP "sentimento_cores". Desta forma a função "mostra_sentimentos" vai somente pegar o valor do input diretamente do array javascript sem a necessidade de uma requisição ajax.

Até aí tudo bem. No entanto se você testar este código vai perceber que um erro javascript vai aparecer logo de cara na seguinte linha:
sentimentos_cores.push("depressão, luto e "escuridão"");
Como a palavra escuridão está entres aspas duplas estas se misturaram com as aspas duplas do código javascript formando um comando inválido. O problema aqui foi que nós não escapamos a saída javascript. E como já comentei em um artigo anterior não escapar a saída pode trazer sérios problemas para sua aplicação web.

E como escapamos a saída javascript? Muito simples, a linguagem PHP já possui uma função que faz isso, embora o nome da função não seja óbvio, a função json_encode. Assim o trecho onde a PHP gera o código javascript ficaria assim:



Agora vá e observe a saída gerada pela linguagem PHP:



As aspas foram escapadas e os acentos foram convertidos para uma representação unicode. Na verdade nós poderíamos ter simplificado o código usando a função json_encode diretamente no array PHP o teria gerado a seguinte string:

["al\u00edvio e paz","amor e paix\u00e3o","depress\u00e3o, luto e \"escurid\u00e3o\""];

Esta string é código javascript, e pode ser usado diretamente no código javascript da página:



Espero que este post seja útil para quem estiver usando PHP para gerar javascript, até a próxima!

segunda-feira, 28 de novembro de 2011

Sobre como montar árvores armazenadas em bancos de dados relacionais

Sumário: Neste post vou falar sobre como montar a árvore de relacionamentos de uma estrutura hierárquica armazenada em uma tabela de um banco de dados relacional, e em seguida aplicar isso na exibição de um select(html) onde os relacionamentos entre pais e filhos são demonstrados. Download de código de exemplo no final do post.

Em um projeto que ajudo a desenvolver no trabalho, um CMS, temos uma tabela no banco de dados chamada Páginas. Esta tabela armazena informações sobre as página de um site, estas páginas indicam cada local de conteúdo de um site, como Home, Busca, Notícias, etc. Acontece que as páginas são inter-relacionadas, ou seja, a página Home pode ser pai da página Notícias e a página Notícias pode ser pai da página Destaques. A estrutura simplificada da tabela Página é a seguinte:
Tabela Páginas
id nome id_pagina_pai

1

Home

null

2

Notícias

1

3

Destaques

2

4

Busca

1

5

Menu

null

Como vocês podem ver a coluna id_pagina_pai é uma referência a coluna id da mesma tabela, por exemplo, olhando no registros da tabela podemos ver que a página Destaques é filha de Notícias.

Este tipo de estrutura hierárquica é muito comum em muitos softwares e sistemas e no dia-a-dia como relações familiares, grupos e sub-grupos, sistemas de arquivos com suas pastas e sub-pastas e muitos outros. Acontece que bancos de dados relacionais não são as melhores ferramentas para armazenar e manipular estes tipos de informações. Por exemplo, como faríamos para exibir a estrutura da tabela de Páginas mostrada acima em um select html da seguinte forma?:



No código exemplo que pode ser obtido abaixo eu demonstro a forma que eu encontrei para fazer isso. Provavelmente não é a melhor forma, mas resolveu meu caso muito bem. Só lembrando que em bancos de dados como Oracle e Postgre existem recursos como queries recursivas que ajudam na hora de manipular dados hierárquicos. No exemplo estou usando o banco de dados Mysql.

A Função que faz a Mágica
O principal trecho do código é função create_pool_tree, reproduzida abaixo:


Esta função basicamente cria toda a árvore que está armazenada na tabela paginas usando referências dentro de um array. Um pouco difícil de entender? Vamos por partes:

O primeiro foreach do código basicamente pega todas as páginas e as coloca em um array com uma estrutura pré-preparada. A imagem abaixo vai ilustrar o processo tomando como exemplo os dados da tabela Páginas acima:
Array $pool

Cada quadrado destes é um elemento do array $pool. Os nomes Home1, Noticias2, Destaques3, Busca4 e Menu5 são os índices. O índice pagina dentro de cada item é o objeto pagina. E filhas é um array vazio por enquanto.

O próximo foreach vai criar referências onde cada item de $pool vai ser referenciado por uma referência no array filhas de seu pai que também está em $pool. Complicado? A figura abaixo deve ajudar:
Array $pool com as refrências.

Vejam que todos os elementos estão no array e como as referências nos permitem saber a estrutura da árvore. Observem como Home e Menu não são referenciados por ninguém, o que significa que são os nós raízes da árvore.

O link para download do código exemplo está logo abaixo. São apenas dois arquivos, um de código php e outro com o banco de dados exemplo. Acho que o código não deve ser muito difícil de se adaptar para as necessidades de cada um. Qualquer dúvida, sugestão ou crítica sou todo ouvidos.


segunda-feira, 14 de novembro de 2011

Mais um pequeno Jogo que desenvolvi - DarkMatters

Link para o jogo

ScreenShot:


Um pequeno jogo desenvolvido usando Flixel e a biblioteca Flixel Power Tools, usada pelo método de colisão usando a transparência dos sprites. Devo dizer que demorei muito mais tempo do que eu imaginava para finalizar este game, e é um jogo bem simples, mesmo!

sábado, 29 de outubro de 2011

Escapar saída html em PHP

Você está escapando a saída de todo o conteúdo inseguro nos seus scripts PHP? E por conteúdo inseguro eu digo tudo o que não for interno da aplicação como qualquer informação enviada pelos usuários, dados de outros servidores, webservices, banco de dados etc.

Uma boa notícia é que se você usa algum dos modernos frameworks php (Code Igniter, Symfony, Cake PHP) corretamente ele provavelmente já está cuidando disso para você, mas é bom você checar só por precaução. O problema é que muitos de nós desenvolvedores PHP temos sites ou sistemas que já tem um bom tempo de estrada e não usam nenhum framework.

Agora, você deve estar se perguntando, o que é este negócio de escapar a saída (output escape)?! Bem, como você deve saber desde os primórdios da internet a principal função de um browser web é exibir documentos html. E um documento html nada mais é do que um arquivo de texto, formado por tags html e texto puro. Aqui vai um exemplo de um típico trecho de um documento html:


Como você pode ver neste trecho de html temos um pouco texto comum, mas também temos as nossas famosas tags. As tags nada mais são do que comandos para o browser. Insira um imagem aqui, uma parágrafo aqui e crie uma div neste ponto...

Como o browser identifica estas tags? Através de caracteres especiais como < e >. Existem alguns outros caracteres importantes como ', " e &. E o que isso tem a ver com escape de saída? Bom imagine que em um blog um dos usuários insira um comentário com um conteúdo como este:


O que você acha que vai acontecer? Bom o browser de qualquer visitante que exibir este comentário vai executar o que quer que esteja no script perdeu_mane.js. Podem ser ações desde de redirecionar o usuário, exibir anúncios, quebrar o layout do site, roubar senhas e cookies, e até mesmo fazer com que usuários logados com previlégios de administrador executem ações no site. Isso meu amigo, é o famoso ataque XSS(Cross-site Scripting).

Escapar a saída nada mais é do que exibir aqueles caracteres especiais de uma forma representativa fazendo com que o browser não execute nenhuma ação disparada por tags. Neste caso < e > são escritos como &lt; e &gt;.

Uau! E como eu faço isso? Bom, escapar exibição de html em PHP não é particularmente difícil.
Exibir texto simples em uma página web:


Exibir text simples dentro de uma tag html:


Se você sempre usa aspas-duplas " nas suas tags, como por exemplo <input type="text" name="nome aqui" /> você pode usar ENT_COMPAT ao invés de ENT_QUOTES. ENT_COMPAT diz para a função transformar apenas as aspas-duplas, ENT_QUOTES vai transformar tanto aspas-duplas quanto aspas-simples.

Importante! Quando escapar a saída?
Você deve estar pensando que ao invés de ficar sempre chamando a função htmlspecialchars na hora de exibir o conteúdo você pode chamá-la apenas uma vez na hora de salvar o conteúdo? Talvez não seja uma boa ideia, hoje em dia é muito provável que você não vai exibir seu conteúdo apenas em páginas html, você também tem rss, json, csv, arquivos texto, emails e outras opções. Para cada uma destas opções de exibir conteúdo o processo de escape é diferente. Se você quiser salvar processamento você pode armazenar uma versão inalterada do conteúdo junto com versões já escapadas de acordo com sua necessidade.

Por enquanto é isso pessoal, espero que o artigo seja útil a vocês.

sábado, 17 de setembro de 2011

Rodar aplicativos 32-bit no Linux 64-bit

Computador novo, nova instalação do Ubuntu, desta vez a versão 11.04. E desta vez a versão 64-bit do sistema operacional, afinal, agora eu tenho 8 GB de memória ram e sistemas 32-bit não podem reconhecer mais do que 4 GB.

Quando estava testando alguns programas que costumava rodar no sistema antigo, como o flashplayerdebugger, o sistema estava me retornando uma mensagem dizendo que não tinha encontrado o arquivo ou diretório, apesar do caminho estar correto. Depois que algumas buscas sem resultado algum tive a ideia de que o problema poderia ser o fato de agora o programa estar em um sistema operacional 64-bit. Procurei para se achava uma versão 64-bit do flashplayerdebugger sem sucesso. Então procurei como rodar programas 32-bit em um sistema 64-bit.

Finalmente encontrei este post. Instalei a biblioteca indicada ia32-libs e pude rodar o programa. Aparentemente existem diversos problemas para rodar aplicativos 32-bit em ambientes 64-bit, pelo menos no linux. Este outro post pode ajudar a resolver os problemas de compatibilidade das bibliotecas.

sábado, 10 de setembro de 2011

Jogo brasileiro no KickStarter

Olá pessoal! Só um post rápido para ajudar a divulgar o game The Light of The Darkness. Este game está sendo desenvolvido por uma equipe brasileira e atualmente eles estão buscando financiamento no site kickstarter. Este site permite que qualquer pessoa possa investir no projeto (eles chamam isso de crowd funding). Você entra no site, escolhe uma quantia que você quer investir no projeto e recebe algum mimo como retorno de acordo com a quantia que você investiu. No caso do The Light of Darkness você pode receber desde wallpapers do jogo, um cópia do jogo no dia do lançamento e até ter o logo de sua empresa como patrocinadora do projeto junto com um vídeo de divulgação.

Quanto ao jogo, ele parece uma excelente mistura de ação, aventura e exploração com gráficos 2D de alta qualidade. Espero que eles consigam juntar a quantia de que precisam, é legal ver estas iniciativas de densenvolvimento de jogos no Brasil.

segunda-feira, 22 de agosto de 2011

Terminator

Não. Este post não é para falar sobre o filme "Exterminador do Futuro". Vim aqui para falar da excelente ferramenta chamada Terminator. É uma ferramenta que permite abrir mais de um terminal em uma mesma janela. Uma mão na roda de pessoas que usam bastante a linha de comando como administradores de sistema e programadores da velha guarda.
Para instalar dá uma olhada neste artigo e procure pela sua distro.
Aqui vão algumas dicas para os comandos mais comuns:

  • ctr+shift+o - Abre uma janela horizontal.
  • ctr+shift+e - Abre uma janela vertical.
  • ctr+shift+w - Fecha a janela atual.
  • ctr+shift+x - Minimiza/maximiza a janela atual.
  • ctr+shift+setas - Muda o tamanho da janela atual.
  • alt+setas - Para mudar de uma janela para outra.

Você também pode se sentir um verdadeiro hacker de filmes com vários terminais abertos ao mesmo tempo.

quarta-feira, 3 de agosto de 2011

As grandes Lojas Varejistas mataram o ano do Linux

Computadores de desempenho decente realmente estão baratos hoje em dia. Trinta anos atrás eram coisa de ficção científica, ocupando prédios inteiros e eram cheios de luzes piscantes. Quinze anos atrás já cabiam em uma mesa mas custavam o mesmo que um carro talvez um fusca. Hoje em dia com um pouco mais de um salário mínimo você compra um computador "de escritório" para acessar a internet, ver vídeos, jogar jogos Flash e eventualmente trabalhar em uma planilha do eletrônica ou documento de texto.

Vez ou outra vejo propagandas destas grandes lojas varejistas como Casas Bahia, Ricardo Eletro, etc anunciando computadores "de escritório" mais ou menos pelo preço citado acima. O que me chama atenção é a ênfase de algumas lojas em dizer que o computador é com "com Windows". Principalmente a Ricardo Eletro que ainda adiciona "atenção é com Windows!". Já testemunhei muitas histórias de pessoas que compraram estes computadores mais baratos, percebem que eles vêm com uma versão desconhecida e sinistra do Linux (como se o Linux já não fosse sinistro o suficiente para pessoas que só conhecem o Windows) e optam por instalarem o Windows.

É irônico que o Linux tenha se tornado uma desvantagem competitiva na hora de vender computadores, já que ter ele instalado por padrão deveria pelo menos ajudar a diminuir o preço total da máquina.

Acredito que alguns fatores ajudaram para que esta situação acontecesse. Para começar, as próprias pessoas que compram estes computadores. A maioria delas não deve dar a mínima para qual SO está instalado no computador, elas querem apenas comprar (em muitas parcelas!), ligar o computador e usarem o que já estão acostumadas a usar. Quando vêem aquela interface estranha, ícones diferentes, nomes que elas nunca viram e não acham os programas que estão acostumas a usar, ficam perdidas resolvem instalar o
bom Windows velho de guerra que conhecem do trabalho, da escola, caso do amigo etc. Até aí tudo bem, não sou contra este pragmatismo. O problema é quando usam cópias piratas para isso, afinal no nosso país pagar por software é um conceito tão estranho quanto comer carne de cachorro. Isso não só desvaloriza o Windows como o Linux também. Na verdade é um problema cultural pois já vi pessoas que poderiam muito bem dispor de R$400,00 por uma cópia do Windows mas preferem a versão "jeitinho brasileiro".

Outro fator que joga contra o Linux são estas empresas e fabricantes que instalam estas versões, "customizadas" pelo próprio capeta, nos computadores vendidos. Mesmo que a pessoa resolva dar uma chance ao Linux vai ficar perdida usando uma distribuição Linux que não tem todo o suporte e comunidade da Ubuntu por exemplo.

Finalmente temos as próprias lojas varejistas. Como já disse, com o Linux instalado em um computador por padrão o preço total da máquina diminuiria. Mas estas lojas não se esforçam nem um pouco em explicar que sem um Windows OEM instalado o preço já chamativo diminuiria um pouco mais.

No final tudo se resume a negócios e praticidade. A Microsoft ganha o dela vendendo suas cópias de Windows OEM, as lojas vendem seus computadores "com Windows" e o usuário pode usar o que ele sempre usou e legalizado!

Pelo menos nos servidores o Linux já tem o seu lugar garantido e no mundo mobile ele tem muita briga pela frente.

segunda-feira, 25 de julho de 2011

Template para design de games

Neste post do blog da lunargiantstudios o autor disponibilizou um template do documento de game design de um jogo. Este documento é basicamente o planejamento de como o jogo vai ser. Para os interessados em game design e desenvolvimento de jogos vale a pena conferir.

terça-feira, 19 de julho de 2011

New game on the block

Olá pessoal! Já faz algum tempo que estou trabalhando em um pequeno jogo flash que acabei de publicar no site kongregate. O jogo se chama Linker e é bem simples na verdade. Aqui vai um screenshot do jogo:
Seu objetivo é coletar todas as moedas de prata evitando os inimigos, um único toque e lá se vai uma vida. Seu único poder é quando você coleta a "moeda estrela", que lhe dá o poder de se conectar com os inimigos formando um elo entre vocês. Depois o disso o jogador pode colocar os inimigos presos no elo para dormir por algum tempo.

Este é primeiro jogo que realmente publico, e (espero!) que venham outros. Joguem e me dêem suas opiniões.

segunda-feira, 4 de julho de 2011

Enviar requisição post com curl e PHP

Dica rápida para fazer a linguagem PHP enviar uma requisição to tipo post (no mesmo estilo que um formulário html com method="post") para uma url qualquer.

Aqui está o código que envia a requisição post:



E aqui está o código que recebe a requisição post, processa os valores enviados e retorna o resultado como um trecho de html:



Inspiração original para o código e post no php dev zone.
Bem, é isso aí. Qualquer coisa use sua liberdade de expressão nos comentários.

domingo, 19 de junho de 2011

Serviço de Utilidade Pública

Olhem só que interessante! Acabei de receber duas mensagens SMS com o seguinte conteúdo:
(+732) Sua linha movel foi premiada a uma "CASA" no valor de 79MIL pelo apresentador (CELSO PORTIOLLI) p/ + inf: ligue 0218591606447 Senha.99999
A mensagem veio do número 55-8597064785.

Ó quanta felicidade!

Mas falando sério, isto claramente é um golpe. Provavelmente aplicado por presidiários com tempo e celulares de sobra. Já há algum tempo este golpe vem sendo praticado. Basta buscar por partes desta mensagem SMS na internet para achar vários links com pessoas relatando terem recebido as mensagens e com dúvidas sobre sua veracidade. Só muda o valor do prêmio ou nome do apresentador e emissora. Neste artigo temos um relato sobre uma vítima do golpe.

Geralmente estas mensagens vêm recheadas com erros de português e pedem para que a vítima ligue para um número de celular. Ligando eles pedem para que a vítima transifira dinheiro para uma conta bancária, façam recargas para  outros celulares ou "doações" para hospitais que cuidam de criancinhas órfãs com câncer. Promoções ou concursos legítimos não apresentam estes gastos para o ganhador, e se você nunca efetivamente se inscreveu em algum concurso ou promoção provavelmente só tem chances de cair em um golpe e não de ganhar qualquer prêmio.

Fica a dica pessoal.

PS: Interessante como eles colocaram casa entre aspas na mensagem que recebi. Denotando a ironia de "ganhar uma casa".

sábado, 28 de maio de 2011

Info.php

Qual desenvolvedor PHP que de vez em sempre não precisa rodar o famoso comando phpinfo() em um servidor para ver quais extensões e recursos estão instalados?

E como não é chato ter que criar um arquivo info.php, lembrar corretamente do nome da função, é phpinfo() ou php_info() graças a padronização dos nomes de funções no PHP? Ter que conectar no servidor via ftp ou rsync, enviar o arquivo etc.

Não seria bem melhor ter um script pronto em um lugar estratégico e fácil de lembrar, rodá-lo e depois só acessar o endereço do site no browser e consultar a saída do phpinfo()?

Pensando nisso eu criei um pequeno script PHP que faz exatamente isso. Como o nome de generate_info.php basta abri-lo preencher o nome de usuário, password e endereço do servidor (só ftp por enquanto), dar permissão de execução para o script e rodá-lo assim "./generate_info.php". Prontinho! Basta acessar seu servidor na pasta indicada no endereço do servidor colocando o nome "info.php" no fim da url para ver a saída gerada.

Ah! Mais uma coisa! Não é muito seguro deixar este tipo de arquivo no seu servidor já que ele pode revelar muitas informações para pessoas mal intencionadas. Se você rodar o comando usando o parâmetro "-d" o arquivo info.php será excluído, ex: "./generate_info.php -d".

Para a galera do Windows estes comandos devem funcionar:
php.exe -f "generate_info.php" (criar o arquivo)
php.exe -f "generate_info.php" -- -d (excluir o arquivo)

Use este comando se você tiver o svn instalado para obter o script:
svn checkout http://hipercodigo.googlecode.com/svn/trunk/generate_info

Ou você pode acessar o arquivo diretamente neste endereço:
http://hipercodigo.googlecode.com/svn/trunk/generate_info/generate_info.php

domingo, 15 de maio de 2011

Número de conexões no banco de dados Postgre

No lugar onde trabalho não possuo acesso a estatísticas e recusos administrativos do servidor de banco de dados postgre. Talvez fruto de um ciúme doentio da equipe de banco de dados com seus preciosos servidores. De qualquer forma precisei ver como estava o número de conexões com o servidor, e felizmente o postgre permite que estes número sejam acessados através de simples comandos sql.

Lembre-se de que as configurações para coleta de estatísticas devem estar habilitadas. Estas opções adicionam alguma penalidade na execução de queries. Por padrão as opções que permitem usarmos o comando sql apresentado aqui ficam habilitadas. Caso este não seja seu caso dê uma olhada no arquivo postgresql.conf. Mais detalhes no manual.

Finalmente aqui vai o comando:
select datname, count(*) from pg_stat_activity group by datname;

Com este comando podemos ver o número de conexões ativas no momento de execução agrupando-as pelo nome do banco de dados.
A saída será semelhante a isso:

  datname  | count
-----------+-------
 testdb    |     5
 template1 |     1
(2 rows)

A tabela pg_stat_activity também tem outras colunas com outras informações interessantes:

datid - oid do banco de dados
datname - nome do banco de dados
procpid - id do processo
usesysid - OID do usuário
usename - nome do usuário
current_query - query sendo executada atualmente
waiting - status de espera da query
xact_start - horário em que a transação atual começou a executar
query_start - horário em que a query começou a executar
backend_start - horário em que o processo foi iniciado
client_addr - Endereço do cliente
client_port - Porta do cliente

As colunas que mostram informações sobre a query só podem ser vistas pelo super usuário ou se o usuário que estiver vendo as informações for o mesmo do processo que está sendo listado.
Está aí pessoal uma dica rápida, espero que seja útil à vocês.

quinta-feira, 17 de março de 2011

Criar banco de dados Postgre com encoding Latin1 em um sistema UTF-8

Estes dias eu estava passando por uma pequena dor de cabeça. Meu sistema operacional que uso para desenvolvimento (Ubuntu 10.10) está configurado com o encoding utf-8 e o locale para pt_BR. Acontece que eu estava tentando usar o pgAdmin III para criar um banco de dados com encoding Latin1 (o nosso famoso ISO-8859-1). Eu abria o pgAdmin, mandava criar um novo banco de dados, dava um nome para ele, na opção codificação escolhia LATIN1, dava ok, e pimba! Recebia a seguinte mensagem:
Um erro ocorreu:

ERRO:  codificação LATIN1 não corresponde a configuração regional pt_BR.utf8
DETALHE:  A definição de LC_TYPE escolhida requer codificação UTF8.


Eu recitava uma meia-dúzia de nomes feitos mas não sabia o que fazer. Eis que a luz veio da singela resposta deste cara no StackOverflow. Fui para o terminal, loguei como o usuário postgres, e executei o comando da seguinte forma:
createdb -T template0 NOME_BANCO -E LATIN1 --locale=pt_BR
E pimba novamente! (Desta vez um pimba bom). Funcionou mesmo, tenho um banco chamado NOME_BANCO com encoding LATIN1 em meio a outros bancos com encoding UTF-8.

StackOverflow salva o dia novamente.

segunda-feira, 21 de fevereiro de 2011

Acabando com as entradas de sites repetidas do Filezilla

No local onde trabalho para pagar as contas, eu e toda a equipe que trabalha comigo usamos regularmente o programa Filezilla para transferências de arquivos por ftp, para atualizar os servidores web rodando nosso código PHP por exemplo. Pessoalmente acho o FTP lento e ele possui poucos recursos comparado com alternativas bem melhores como rsync. Uma brincadeira com o acrônimo F.T.P é que ele significa "Foi-se o Tempo Peixe". Por motivos alheios a mim ainda usamos FTP.

O Filezilla é um excelente programa para fazer transferências FTP. Mas temos um pequeno problema com ele. Quando importamos um arquivo xml com os dados de um servidor FTP gerado pelo Filezilla acabamos com entradas duplicadas na tela "Gerenciador de Sites". Isso é bem frequente no nosso caso pois temos mais ou menos 40 sites. E para completar a bagunça os dados de servidores podem estar diferentes com servidores com senhas ou usuários alterados.

Pensando numa forma de unificar as listas de servidores FTP geradas pela exportação do Filezilla eu cheguei a um pequeno programa para fazer isso. É escrito em PHP e funciona na linha de comando. O uso é bem simples, após dar permissão de execução para o arquivo "unify.php" basta executar o seguinte comando:
./unify.php "diretório"
Você deve ter o PHP instalado obviamente. No windows você pode usar algo como php unify.php "diretório".

Onde está escrito "diretório" você deve colocar o caminho de uma pasta onde todos os arquivos xml gerados pelo Filezilla estão. Depois de processar e mostrar alguma saída o programa vai gerar um arquivo chamado output.xml dentro da pasta output. Pronto! Este arquivo output.xml pode ser importado novamente no programa e deve conter somente entradas únicas. No programa eu considero entradas únicas os servidores que estão registrados com nome de usuário, endereço de servidor e senha diferentes.

Caso você tenha entradas repetidas no Filezilla, basta você exportar usando a opção "Arquivo->Exportar...-> Escolha Exportar entradas do gerenciador de websites". O Filezilla irá gerar um arquivo xml. Rode o programa de acordo com o comando mostrado acima, e o arquivo gerado, output.xml, irá conter somente entradas únicas.

É claro que antes de importar o output.xml você deve limpar os sites já registrados no Filezilla, ou você terá entradas duplicadas novamente. No Filezilla (eu uso a versão 3.2.7.2) aparentemente não tem uma opção para excluir todas  as entradas de uma vez só. No linux, você pode apagar manualmente as entradas do arquivo sitemanager.xml localizado em ~/.filezilla/sitemanager.xml. Você pode apagar todas as tags "Server" ou deixar somente uma, assim você só terá que apagar uma quando importar o arquivo output.xml.

O programa atualmente considera que todos os sites registrados estão dentro da mesma pasta no Gerenciador de Sites. Provavelmente ele gera um xml diferente para várias pastas. E caso seus arquivos gerados pelo Filezilla sejam muito grandes o programa pode alcançar o limite de memória de execução do script, neste caso você pode aumentar o limite usando "ini_set('memory_limit', '128M');" dentro do próprio script logo na primeira linha php.

domingo, 30 de janeiro de 2011

CodeIgniter 2.0 Liberado!

Hoje fiquei sabendo do lançamento do CodeIgniter (CI para os íntimos) versão 2.0. Já fazia mais de um ano que eles estavam trabalhando nesta versão. O anúncio oficial do lançamento e informações sobre as mudanças podem ser vistos em todos os detalhes no site oficial.

Algumas mudanças notáveis foram o abandono da versão 4 do PHP (que já estava na hora, será que alguém ainda usa PHP 4?). Agora o framework tem suporte nativo a query strings, uma falta considerável nas versões passadas na minha opinião. Outra coisa legal foi a adição de suporte para execução de scripts via linha de comando facilitando a criação de cron jobs, se bem que isso já era possível antes com o uso de bibliotecas. Além disso temos as tradicionais correções de bugs e melhorias no código.

O CodeIgniter é um framework PHP muito simples de se usar e instalar. Funciona praticamente em qualquer host compartilhado que você encontrar. Além disso te ajudar com todo aquele trabalho feijão com arroz que sempre tem que ser feito em coisas como upload de arquivos, validação de formulários, envio de emails, sql injection, prevenção de ataques XSS etc. Tem uma comunidade muito ativa e uma excelente documentação através de seu guia do usuário.

domingo, 16 de janeiro de 2011

Sheldon Cooper é um péssimo gerente de projetos

Estes dias eu assisti ao 12º episódio da 4º temporada de "The Big Bang Theory" onde o personagem Leonard tem a ideia de criar uma app para fazer o reconhecimento de equações através de fotos tiradas pelo telefone. Ele conta a ideia para os outros personagens e os chama para participarem do projeto.

Este episódio é muito interessante pois ele demonstra através do comportamento do Dr Sheldon o que acontece em muitas equipes engajadas em desenvolver softwares ou outras atividades.

  • Exagero de detalhes em partes do projeto que não são essenciais para o início da empreitada. Logo no começo Sheldon traça uma lista indicando os cargos e responsabilidades de cada integrante do projeto. Não que isso seja uma coisa errada, mas ele realmente exagera ao, por exemplo, escolher o líder do comitê de Amigo Secreto (no caso ele mesmo). Isso é muito comum em projetos de desenvolvimento de aplicativos, o que geralmente leva ao fracasso. Um exemplo comum é quando uma equipe resolve detalhar vários casos de uso diferentes para uma aplicação. O que temos que levar em conta é que geralmente um aplicativo deve fazer pelo menos uma coisa bem feita. Tente detalhar esta parte primeiramente e depois mais para frente pense sobre o processo de login do usuário ou como vai ser a disposição do menu.
  • Não foca em partes do projeto que contribuem para o objetivo principal. Tem muito a ver com o primeiro ponto mas aqui estamos falando mais de execução do que planejamento. Logo no início do projeto Leonard resolve discutir sobre a interface do programa, o que eu acho que toda equipe de desenvolvimento de software deveria fazer. A primeira e talvez unica coisa que o usuário enxerga de um programa é a sua interface. Para o usuário a interface é o programa. Acertar em uma interface limpa, não ambígua e eficiente já é meio caminho andado em direção ao sucesso quando estamos desenvolvendo aplicativos. Quando Leonard comenta que quer começar a discutir a interface do usuário Sheldon prontamente diz algo como "Estamos ferrados.". Isso sem contar a parte onde no meio do desenvolvimento ele resolve introduzir uma discussão sobre nomes para o aplicativo. Lembrem-se, primeiro façam o aplicativo fazer algo útil depois se preocupem com o resto.
  • Equipe engessada. Em determinando momento Sheldon resolve que Raj será responsável pelo suporte telefônico (o que é um pouco racista) e Howard será seu assistente pessoal. Usar dois caras inteligentes como eles (Howard inclusive é um engenheiro) para dar suporte por telefone e comprar comida para o time?! Eu acho que a série realmente exagerou neste ponto, mas o que eu gostaria de comentar é sobre esta postura de definir papéis inflexíveis para os membros de uma equipe. "Você só trabalha com o banco de dados!" "Eu vou somente programar!" "Você cria a interface e nada mais." É claro que temos que ter pessoas que dão a última palavra ou teríamos discussões intermináveis. Mas para um projeto dar certo uma equipe precisa ser extremamente comunicativa e estar aberta a opiniões uns dos outros. Precisamos ter uma visão do projeto como um todo ou chegamos naquele ponto onde cada membro tem sua opinião divergente sobre o real objetivo do que estão fazendo.
  • Sheldon não sabe trabalhar em equipe. Eu odiaria trabalhar em uma equipe com alguém como o Sheldon. Ele não sabe expressar suas opiniões para outros membros, ele não consegue ser construtivo ao criticar outra pessoa. Sempre existirão conflitos dentro das equipes responsáveis pelos projetos, mas sempre que você for criticar o trabalho de outra pessoa tenha argumentos lógicos e evite usar de oratória vazia ou sua posição ou status.
Bom pessoal estes são os comentários que eu tenho a fazer sobre o episódio, ele ficou muito bom e recomendo que assistam a série pois ela é muito divertida. E vocês? O que tem a dizer?

tl;dr
Inicialmente foque nos aspectos que tornam uma aplicação realmente útil. Não crie "ilhas" dentro de sua equipe onde as pessoas não se comunicam. Seja lógico e consistente ou criticar o trabalho de outra pessoa.

sexta-feira, 7 de janeiro de 2011

Dica Útil

Todo programador vez ou outra dá uma olhada no manual de referência de funções da linguagem sendo usada. No PHP esta necessidade é ainda maior já que é sempre muito difícil lembrar se o nome daquela função tem um underline ou qual a ordem correta dos parâmetros. Os desenvolvedores da linguagem PHP não devem gostar de padrões de codificação.

Aqui vai uma dica para tornar mais rápido o acesso a referência das funções. Eu uso um sistema Linux mas com algumas modificações ela pode ser adaptada para Windows também.

Crie o arquivo "php.net" no seguinte diretório (ou qualquer diretório disponível no seu PATH):
/usr/local/bin

Digite o seguinte no arquivo:
#!/bin/sh

google-chrome --new-window "http://www.php.net/$1"

Eu usei o chrome mas você pode usar outros browsers levando em consideração os parâmetros de cada browser.

Dê permissão de execução com o seguinte comando:
sudo chmod +x /usr/local/bin/php.net


Pronto!
Agora você pode digitar na linha de comando ou usando o atalho Alt+F2 no gnome:
php.net str_replace
e uma nova janela do chrome vai abrir na página com o manual da função str_replace.

É isso aí! Espero que isso possa ajudar a todos!

terça-feira, 4 de janeiro de 2011

Sistema de recomendação de palavras em PHP

Você tem ideia de como implementar aqueles algoritmos de recomendação de palavras? Como por exemplo no google onde se você digita "paola olivera" ele ter retorna a página de resultados com a famosa frase "Você quis dizer: paola oliveira". Eu não sei como implementar um e este cara aqui provavelmente também não sabe. Mas ele conseguiu o objetivo de uma forma muito criativa utilizando PHP.