Páginas

5 de mai de 2014

Corrigindo erros de caracteres (charset) no MySQL

Um dos problemas mais comuns, e mais silenciosos, no desenvolvimento web é a utilização correta do mapa de caracteres ou charset. O charset é um mapa que relaciona um determinado caractere com seu equivalente, seja em bits, pulsos elétricos ou qualquer outra forma que facilite a correta transmissão e compreensão do símbolo em questão. Atualmente, acredito que os mais utilizados sejam o Latin1 (ISO-8859-1) e o Unicode UTF-8 . Sendo assim, devidamente apresentados, vou citar o problema que tive justamente com esses 2 charsets e como resolvi esse problema definitivamente.

A Problemática do Silêncio 


Em muitos casos, a utilização errada de um mapa de caracteres é logo descoberta, pois o sistema começa a não exibir o caractere que deveria. O problema é quando sua aplicação está sendo impactada pelo problema e a própria aplicação está te prevenindo de ver o problema. Para ambos os casos, acredito que essa solução pode sanar quaisquer problema de charset trocado ou mal utilizado.

O problema que me deparei acontecia no seguinte cenário:
O banco de dados foi criado com charset default Latin1 e suas tabelas também. Com passar do tempo, novos desenvolvedores começaram a criar novas tabelas, agora em charset utf-8. Em pouco tempo, nos deparamos com um grande “mix” de Latin1 e utf-8 em nosso banco de dados. Nesse momento, como tínhamos mais tabelas utf-8, parecia lógico migrar todo o banco para utf-8 e padronizar tudo.

Descobrimos o Real Problema!


Silenciosamente, as tabelas utf-8 foram sendo populadas com dados que estavam utilizando Latin1, tudo devido a conexão padrão do MySQL configurar o charset padrão de acordo com o chartset padrão do banco e não de acordo com a tabela. Nesse ponto, temos tabelas Latin1 e utf-8, ambas com dados salvos utilizando Latin1. Esse problema não nos impactava ou a nenhum de nossos sistemas, devido ao script de conexão ser 1 único para toda aplicação.

Um Problema que não causa Problema? 


Sim, esse problema não afetou, prejudicou o chateou nenhum de nossos usuários, ninguém viu uma “?” no lugar de “ç”. Muitos poderiam pensar em manter as coisas como estão, a aplicação gravando e lendo corretamente, mesmo que dentro das tabelas erradas. Porém, sabemos que tudo tende a evoluir, sabemos que um dia iremos necessitar de funcionalidades específicas do Unicode, como o “Accent-Insensitive” do MySQL para buscas normais e com FULLTEXT INDEX, conexões de outras fontes, como smartphones, web services… Enfim, as possibilidades para problemas futuros são reais.

Solução 


A solução é demasiadamente simples quanto tem-se um banco de dados pequeno (<2Gb), porém quanto o banco está relativamente grande, a dificuldade cresce, por isso, caso você tenha detectado esse mesmo problema ou semelhante, aconselho agir e solucionar (utilizando minha solução se desejar =] ) o mais rápido possível.

Eu estou usando MySQL 5.5 e, para o meu objetivo, vou converter um banco com Latin1 e utf-8 misturados para um banco somente utf-8.

Mão na Massa


1. Fazer backup lógico completo do banco forçando o backup a ser realizado com o mesmo charset o qual a aplicação usou para salvar os dados nas tabelas. No meu caso, Latin1. Simultaneamente, estou usando o “|” (pipe) e o comando replace para substituir qualquer ocorrência latin1 por utf8. Atenção, caso exista ocorrência da palavra “latin1” nos dados, tais dados também serão alterados. Caso seu seu arquivo gerado seja muito pequeno, abra-o e edite manualmente os chatsets. Uma alternativa é o comando sed onde é possível especificar uma expressão regular mais “fina” para troca. No final, faço uma simples compactação com gzip por questões de espaço.

mysqldump -Cv --compact --add-drop-table --dump-date --single-transaction --quick --skip-comments --default-character-set=latin1 -u USUARIO -pSENHA -h HOST DATABASE | replace latin1 utf8 | gzip > db_dump.sql.gz

1.1 Caso prefira usar o sed, aqui vai um exemplo que faz a mesma substituição feita acima, porém o arquivo não pode estar compactado.

sed -i 's/latin1/utf8/g' db_dump.sql
1.2 Em alguns casos, se o banco recebeu dados provenientes de várias conexões com charsets diferentes, ainda há esperança! O comando iconv pode ser a luz no fim do túnel. Esse comando converte strings de um mapa de caracteres para outro de maneira simples. Convertendo o arquivo do exemplo acima, ficaria:

iconv -f LATIN1 -t UTF8 -o new_file.sql db_dump.sql

2. Segundo passo, repor o backup. Aconselho criar um novo banco de dados com ambos, “SET NAMES” e “COLLATE” padrão configurados para o próprio banco e também para cada uma das tabelas. No meu caso, como quero que todo o meu banco fique padronizado como utf-8, tenho que importar forçando o novo charset. Tudo pronto, basta executar o comando abaixo (caso você tenha feito backup da maneira mostrada no item 1):

gunzip < db_dump.sql.gz | mysql -u USUARIO -pSENHA --default-character-set=utf8 DATABASE

3. Nesse momento vamos aos testes. Para tirar prova que seus dados agora estão com charset correto, basta conectar utilizando o charset antigo e realizar uma consulta SQL que retorne algum texto com caracteres especiais. Nesse primeiro teste, os caracteres devem vir errados. Conectando novamente, dessa vez com o novo charset (No meu caso utf-8), a mesma consulta deverá retornar os caracteres especiais corretamente. Confirmado que o charset foi alterado com sucesso, agora é garantir que todos os seus scripts de conexão utilizem o mesmo charset, e que nenhum outro programador crie novas tabelas utilizando outro charset ou collate.

Caso algo tenha saído diferente do demonstrado aqui, segue o ambiente que utilizei para executar cada um desses passos. No servidor, estou utilizando CentOS 6.x com MySQL 5.5 via unix socket. No cliente, como máquina de trabalho, utilizei um ubuntu-gnome 13.10 com MySQL 5.5 do repositório oficial do ubuntu via unix socket.

Para visualizações, depuração de erros e criação de tabelas e bancos de dados, utilizo o phpmyadmin e MySQL Workbench.

Dúvidas, reclamações, correções, incrementos, tudo é muito bem vindo!

Leia no Google Drive!

30 de abr de 2014

Como diferenciar chamadas via Servidor Web ou Linha de Comando no PHP

Algumas vezes, aplicações necessitam de código PHP sendo executado diretamente de seu cliente de linha de comando (CLI). Exemplo corriqueiro acontece quando vamos configurar o cron para executar certos scripts em nosso servidor de forma agendada.
Normalmente, quanto criamos esse tipo de script, sua função está fechada a somente ser executado pelo cron. Não é interessante que o servidor web permita execução desse script através da internet ou localmente.
Existem várias formas para alcançar esse objetivo, bloquear especificamente esses scripts no seu apache ou nginx, armazenar fisicamente os scripts em diretórios fora do alcance web ou (mais simples) não permitir que seu script seja invocado por qualquer outro método, senão o CLI. Isso pode ser feito de maneira simples utilizando a função php_sapi_name()

function isCli(){
    return (php_sapi_name() == 'cli');
}

if(isCli())
    print 'Rodando na Linha de Comando';
else
    print 'Rodando em algum outro lugar';

O PHP sempre irá responder “cli” para a interface de linha de comando. A resposta de retorno quando for Servidor web, vai depender do ambiente configurado. Em Ubuntu, Debian e derivados, a resposta será algo como, “apache2handler”.

Leia no Google Drive!

13 de ago de 2012

Amazon SES ( Simple Email Service )


Continuando com os serviços da Amazon, vou abordar um tema que deve ser um dos pontos de grande interesse para qualquer empresa. O envio de e-mail. Para algumas este assunto é mais importante que para outras, seja qual for o nível de relevância para o modelo de negócio da empresa, e-mail sempre é um assunto complexo e que irrita desenvolvedores e empresas há bastante tempo.

Existem várias formas de enviar emails. Criar uma estrutura de envio própria, instalar e licenciar um serviço de email terceirizado, contratar um serviço de envio especializado. Todos têm seus problemas, sendo um deles, o alto custo. Além disso todos sofrem do mesmo problema, o spam. Regras de palavras, imagens, título, do que pode-se ter no conteúdo e o que não. Todos esses problemas são comuns a qualquer tipo de sistema que enviará emails através da internet. Enviar emails com a certeza que terão 100% de taxa de entrega é uma utopia. Existem métodos, dicas e muitos artigos com dicas sobre. Recomendo esse link com bastante material, em inglês.

Após toda essa explicação, então, porque o Amazon SES?

O Simple Email Service ( Serviço de Email Simples, em tradução livre ) não é somente um serviço, mas sim, uma infraestrutura completa e projetada para o envio otimizado de emails. Atualmente é esse serviço que a própria Amazon utiliza para envio de email de todos os seus serviços, conhecidos e utilizados mundialmente. Essa infraestrutura, segue todos os padrões ISPs com o adicional de existir, com qualidade, há muito tempo no mercado.

Como desenvolvedor, o que muito chamou minha atenção foi o modelo de envio do SES. Fazendo uma chamada à API ou enviando diretamente para o endereço de SMTP do SES você está apto para enviar emails pelo SES, porém, o processo não termina nisso. Após um email ser enviado, a infraestrutura do SES digitaliza esse email e o submete a testes e filtros de spam. Caso o email passe em todos os testes, este será enfileirado para envio, caso contrário, o email, com uma mensagem de erro, será enviado para o Return-Path configurado para devidas correções. A grosso modo, a Amazon não vai se comprometer e enviar um email fora dos padrões, arriscando sua reputação e anos no mercado. (Então, caro spammer, essa não é pra você ¬¬ ).

Dentre os dois modos, escolhi utilizar a API fornecida pela Amazon. Seja por ter considerado-a mais simples e segura, seja por acreditar em um melhor desempenho com a mesma. Após criar uma conta na AWS é criado uma chave e uma chave secreta para utilização da API. Essa API contempla praticamente todos os serviços oferecidos pelo Web Services Amazon. Não está no escopo desse artigo percorrer todas as APIs, vamos nos concentrar no SES, por agora.

Criando o awsSesMailer


A amazon possui uma ótima API com documentação extensa, porém com pequena base de desenvolvimento brasileira ou em português. Sendo assim, decidi criar uma ponte, uma maneira a qual os desenvolvedores estejam mais acostumados. Motivos para tal, são claros. Seja a facilidade de uso, a menor curva de aprendizado e tempo de implantação, assim como, manutenção por outros desenvolvedores que não tiveram introdução e estudo da API completa do SES.

O awsSesMailer é uma classe PHP que extende o SDK disponibilizado pela Amazon na linguagem PHP. A utilização dessa classe é muito simples. O desenvolvedor que já utilizou o conhecido phpMailer encontrará métodos praticamente iguais, em nome como utilização.

A documentação está sendo criada, assim como a classe. Qualquer ajuda é muito bem vinda!

https://github.com/marcosbrasil/awsSesMailer

API e SKD da Amazon para PHP


Quem ficou interessado em conhecer todas as possibilidades do SKD disponibilizado pela Amazon, que abrange não somente o SES mas todos os outros serviços agraciados com a possibilidade de uso via API, segue alguns links bem úteis.

README completo do SDK pela própria Amazon

Repositório oficial da Amazon no github


Leia no Google Drive!

12 de ago de 2012

Notas de um domingo à tarde 12/8

Open Source

Observe os últimos anos, as empresas estão em êxtase pois existem tecnolgias maravilhosas e existe material disponível de como utilizá-las. Com isso, não precisamos reinventar a roda a cada novo projeto, isso poupa tempo, dinheiro, nos deixa mais socais e todos ganham.

Para quem ainda não entendeu, isso tem nome, “Social OpenSource”.

Sou muito feliz por fazer parte de um dos grupos que primeiro começou a se beneficiar dessa ideologia. O software. As empresas desenvolvedoras de software e os próprios desenvolvedores devem muito do que sabem e possuem a essa filosofia. O próprio software deve a essa ideia. Temos computadores utilizando software desenvolvido por várias pessoas ao redor do mundo, o projeto Linux é um grande nome, porém, ele não está só, software em robôs, em grande parte da administração dos governos até mesmo na marinha dos EUA já utilizam essa ideologia.

Existe um lugar para os “opensourcers”, uma rede social, github!

Esse processo está avançado e cada dia estou mais feliz. Empresas que ainda pensam de modo fechado, retrógrado, que possuem visão pequena, estão fadadas a continuarem se enganado, “tapando o sol com peneira”. Empresas são feitas de desenvolvedores, estes, detém o real conhecimento da empresa. Sem o compartilhamento, essas empresas nem existiriam. Desejando ou não, o compartilhamento, o social, já chegou, se instalou e crescerá assistindo as ideias egoístas e idiotas do passado falirem, aos poucos, as empresas que fazem delas sua base.

Leia no Google Docs!

7 de ago de 2012

Entendendo o AWS - Amazon Web Services


Recentemente tive a oportunidade de começar a trabalhar com a plataforma de serviços web da Amazon, o Amazon Web Services ou AWS. A amazon, um dos grandes líderes nos serviços web, iniciou em 2006 sua plataforma Cloud-Computing e acredito que todos conheçam esse fantástico conjunto de ferramentas denominado AWS.

O AWS contempla um leque muito grande, um conjunto de ferramentas capazes de hospedar qualquer aplicação de qualquer tamanho, uso ou complexidade. Até então, parece que simplesmente temos um “super-cloud”, mas, na verdade, o AWS tem um conceito de uso diferente das hospedagens que oferecem máquinas cloud-computing, muito famosas e em crescimento.

Para entendermos os conceitos por trás da plataforma Amazon, vamos, primeiramente, rever qual o conceito de cloud-computing que temos hoje. Acredito que o conceito de cloud-computing esteja bem sólido na mente da maioria dos desenvolvedores, principalmente os web. Cloud-Computing então, de modo simplório, seria uma máquina virtualizada dentro de um servidor de alta performance em algum datacerter de algum lugar. Termos controle total sobre essa máquina é importantíssimo quando temos uma aplicação com um nível de complexidade maior que o comum. Nessa versão virtualizada de máquina, são instalados todos os componentes necessários para o funcionamento da aplicação. Desde um portal com milhões de acessos à um web service para um aplicativo iOS, por exemplo.

O novo conceito introduzido pela Amazon, na verdade, está em suas instâncias computacionais. Com essa nova filosofia, a Amazon divide o trabalho feito por aquela máquina virtualizada em várias instâncias de máquina diferentes. Seria uma modularização dos componentes necessários à aplicação. Cada um dos serviços é entregue através de uma nova instância. Esses módulos entregam um um desempenho computacional muito maior com elevado nível de disponibilidade, sendo esta uma maneira bastante efetiva de se implantar redundância de uma aplicação.

Cada serviço oferecido pela AWS está listado em seu AWS Management Console , onde, com alguns cliques, é possível iniciar instâncias para banco de dados, armazenamento, envio de emails ou mensagens além de gerenciador de DNS, gerenciamento de alarmes. Todas ferramentas muito úteis quando se está lidando com aplicações de alta disponibilidade (meu caso).

A seguir, uma rápida definição dos tipos de instâncias que considero as principais no começo do desenvolvimento de uma plataforma sólida. No meu caso, trata-se de um website com alta disponibilidade, número de acessos considerável e elevado envio de emails.

Amazon Elastic Compute Cloud (Amazon EC2)


O Amazon EC2 é a versão amazon para um servidor Cloud-Computing. Como explicado anteriormente, a Amazon otimizou o conceito de instância, uma instância EC2 pode ser criada e posta e funcionamento em questão de minutos. Agregado a isso, existe o conceito chamado “Elastic-Cloud”, também presente nessas instâncias EC2 da Amazon.

Acesso SSH à instância é imediato e chama atenção as funções de segurança ofertadas pela Amazon para esse tipo de Cloud. A possibilidade de criar grupos de segurança, abrir ou fechar portas TCP ou UDP, criar snapshots dentre outros, entrega uma experiência bastante simples, confortável e segura ao EC2.

Amazon Simple Storage Service (Amazon S3)


O Amazon S3 é um tipo de instância amazon especializada em armazenamento. Com elevado nível de redundância e prevenção à falhas e quebra nos arquivos. Pode ser escolhido um entre os vários datacenters da amazon, melhorando assim latência ou economizando os gastos. Sistema de usuários e chaves de autenticação, garantindo a segurança dos arquivos, inclusive, funcionando de acordo com os protocolos internacionais PCI e HIPAA.

Amazon Relational Database Service (Amazon RDS) e Amazon DynamoDB


Aplicações web, em sua maior parte, sofrem de gargalo em banco de dados. Por ser a entrada de dados bloqueante da aplicação, por ser não tão bem configurado ou, na maioria dos casos, não ser bem utilizado por desenvolvedores, o banco de dados sempre requer uma maior atenção.

A Amazon fornece 2 soluções nessa área, também no formato de instâncias. Para atender demandas de dados relacionais, o Amazon RDS é escalável, seguro, com baixa latência e oferece instâncias dos mais conhecidos gerenciadores de banco de dados, como MySQL, Oracle o SQL Server.

Paralelamente, aplicações de alta velocidade e que já fazem uso de tecnologias NoSQL, podem utilizar o Amazon DynamoDB. A plataforma NoSQL da amazon é muito sólida, rápida e escalável. A Amazon garante que todas instâncias DynamoDB estão estruturadas e armazenadas utilizando SSDs.

Amazon Simple Email Service (Amazon SES)


O Amazon SES, atualmente meu objeto de estudo, é a instância Amazon para envio de emails. Com filtros digitais de conteúdo, o SES garante a mínima perda ou bloqueio dos email pelos filtros ISPs anti-spam. Antes do envio, a amazon utiliza filtros digitais para garantir que o email a ser enviado está dentro dos padrões especificados, garantindo assim, um envio de qualidade com a menor perda possível. No console de administração do Amazon SES, é possível visualizar a quota diária de envios, bem como o número de email enviados, rejeitados ou que não puderam ser entregues.

Amazon CloudFront


O Amazon CloudFront é uma ferramenta feita para servir conteúdo da melhor maneira possível. Também conhecida de CDN ( Content Delivery Network ) este tipo de entrega de conteúdo, geralmente estático, é otimizada através de servidores espalhados ao redor do globo, que identificam a origem da requisição, redirecionando-a para o servidor fisicamente mais próximo. Diminuindo lantência e ping de resposta é obtido grande qualidade e velocidade na entrega desse conteúdo. Se existe alguma parte de missão crítica na aplicação, seria uma boa ideia migrá-la para o CloudFront.

Se a ideia for servir conteúdo como fotos, músicas e vídeos, o CloudFront integra-se perfeitamente com o Amazon S3. Tornando a tarefa de armazenar e disponibilizar este conteúdo, muito mais simples, fácil e de grande qualidade.

Tem mais?


Sim, a Amazon ainda tem mais uma dúzia de outros serviços e configurações que podem moldar-se perfeitamente ao seu negócio. Todas elas estão listadas e detalhadamente explicadas no site da Amazon AWS em http://aws.amazon.com/pt/console/ .

Enquanto escrevo este artigo, estou desenvolvendo uma integração para simplificar o envio de emails utilizando o Amazon SES. Logo estará no meu GitHub. Publicarei explicando e atualizarei este artigo, adicionando o link para o próximo artigo. Vamos olhar mais de perto a API do AWS e, em especial, suas funções para envio de emails.

Leia esse documento no Google Docs!

5 de ago de 2012

Notas de um domingo à tarde 5/8

Criamos consciência de nossa existência não sabendo como a própria existência surgiu e perdemos essa consciência sem nunca sabermos o fim da existência por si. Nossa consciência, o que chamamos vida, o nosso conceito de tempo, é apenas uma fração, uma faísca tão rápida que torna-se difícil nota-la.

Você realmente acha que a importância vem no após? No anterior?

O que veio antes da consciência e o que virá depois, é apenas a existência. Bidirecional e infinita em ambas direções. Teus conceitos, teus preconceitos, teus amores, desamores até mesmo tua percepção de tempo, existe agora, enquanto faísca no infinito.

Viver é uma dádiva, não porque você teve a chance de provar algo a algum ser superior. É uma dádiva porque tivemos a chance de sermos mais uma faísca na linha infinita da existência e termos consciência disso!

Leia isso no Google Docs!

29 de jul de 2012

Adicionando suporte ao git para o SublimeText 2

O SublimeText é um editor robusto, completo, muito leve, rápido e multiplataforma. Bem conhecido no Mac e ganhando espaço dentre usuários linux, o Sublime aproxima-se bastante do conceito IDE.

Pra galera que está usando controle de versão com GIT em seus projetos, vamos ver uma forma bem fácil de utilizar comandos GIT diretamente no Sublime.

Sublime Package Control


Para isso vamos instalar agora, o Sublime Package Control. Um sistema de gerenciamento de pacotes muito parecida com a instalação de plugins do Netbeans ou Eclipse, por exemplo.

1. Entre no console do SublimeText com o atalho ctrl+` ou indo no menu View>Show Console. No console cole o seguinte código:

import urllib2,os; pf='Package Control.sublime-package'; ipp=sublime.installed_packages_path(); os.makedirs(ipp) if not os.path.exists(ipp) else None; urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler())); open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read()); print 'Please restart Sublime Text to finish installation'

2. Espere alguns segundos, após, reinicie o Sublime Text

Sublime Text 2 - Git Plugin


Agora vamos instalar o Sublime Text 2 - Git Plugin que irá adicionar a possibilidade de executarmos comandos git diretamente no Sublime.

1. Abra o Command Pallet do Sublime (Command+Shift+p on OS X, Control+Shift+p on Linux/Windows).

2. Selecione "Package Control: Install Package".

3. Quando Git aparecer, selecione e o plugin será automaticamente instalado.

OBS: Não há necessidade em preocupar-se com atualizações. Segundo a Wiki do plugin, elas serão executadas automaticamente.

Para finalizar reinicie o Sublime e abra a Command Pallet. Comece a digitar algum comando git e veja a lista dos comando disponíveis. Isso pode ser uma boa ajuda para quem não gostar de ter um terminal constantemente aberto.

Eu testei essa instalação no Debian 6 com Sublime Text2 v.2.1

https://github.com/kemayo/sublime-text-2-git/wiki
http://wbond.net/sublime_packages/package_control/usage