Por que utilizar utf-8?

Tags: , , — December 14, 2010 @ 8:21 pm

Um problema comum que vejo se repetindo constantemente em listas de discussão é devido a codificação de caracteres em páginas web.

Geralmente os desenvolvedores, inexperientes, solicitam ajuda por terem problemas que fazer caracteres acentuados aparecerem corrompidos, como “çã” e acabam adotando soluções pouco robustas, como editar o httpd.conf (no caso de um servidor web Apache) ou usar funções utf8_encode/utf8_decode (no caso de programação PHP).

Acontece que tais problemas ocorrem por causa de divergências na codificação de caracteres e é mais comum em ambientes Windows, que utilizam a codificação defasada ISO-8859-1 (ou latin-1, como também é chamada).

O modo de evitar este tipo de problema, é desenvolver toda a sua aplicação utilizando uma única codificação de caracteres, desde a base de dados até o HTML exibido para o usuário, e também em seu editor de texto ou IDE. Para garantir isto, por exemplo, em uma aplicação web, desenvolvida com PHP + MySQL, rodando em um servidor Apache2 e utilizando utf-8, atente para os seguintes detalhes:

  1. No arquivo de configuração do Apache (geralmente httpd.conf, mas podendo variar de um sistema para outro, no Debian GNU/Linux, o padrão é /etc/apache2/apache2.conf) comente a linha com a diretiva AddDefaultCharset. Como vamos definir a codificação a nível de aplicação, esta diretiva não irá interferir, mas mesmo assim o ideal é deixá-la comentada para evitar surpresas ao colocar a aplicação em produção.
  2. O PHP também tem uma diretiva para definir a codificação padrão, geralmente desabilitada por padrão, no arquivo php.ini (no Debian, em /etc/php5/apache2/php.ini) localize e comente a linha com a diretiva default_charset. Assim como no Apache, tal diretiva não deve interferir, mas ainda assim é ideal deixá-la comentada.
  3. Garanta que seu template HTML contenha a codificação correta definida no cabeçalho, utilizando uma tag meta (<meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″ />). Para documentos XHTML, também é ideal adicionar a codificação no cabeçalho XML (<?xml version=”1.0″ encoding=”UTF-8″ ?>), obviamente esta regra também se aplica para documentos XML.
  4. Seu script principal da aplicação, ou seja, aquele que recebe as requisições, geralmente index.php, deve enviar um cabeçalho http com a codificação para o navegador antes de qualquer conteúdo. Ex: header(“Content-type: text/html; charset=UTF-8″);.
  5. Suas tabelas do MySQL devem ser criadas com a codificação definida explicitamente. Ex: CREATE TABLE foo (…) CHARACTER SET utf8. No MySQL também é possível definir a codificação de caracteres a nível de coluna ou de base de dados, mas a primeira dificilmente será necessária, e eu acho mais usual definir a codificação a nível de tabelas.
  6. Seu editor de texto ou IDE deve estar configurado para salvar arquivos em utf-8. No Eclipse, por exemplo, basta configurar sua Workspace (Window -> Preferences -> General -> Workspace), ou seu projeto (Clique direito -> Properties -> Resource) para utilizar a codificação desejada.

Para ser sincero, em geral apenas os ítens 4 e 6 são suficientes para garantir que sua aplicação exiba textos na codificação correta, mas ainda assim vale a pena configurar cada parte dela.

Alguns desenvolvedores web mais antigos, ou pouco experientes podem acabar sugerindo que se utilize htmlentities para caracteres acentuados, como “&acute” para escrever um “á”. Contudo esta prática é pouco viável para páginas dinâmicas, devido ao tamanho das strings. Por exemplo, nosso simples “á”, utilizando htmlentities, não poderia ocupar um campo char(1), em sua base de dados, precisando de um char(6), além de ser bem mais conteúdo para o navegador carregar ao visitar a página.

Agora a pergunta: Por que utilizar utf-8 ao invés de iso-8859-1?

Bem, existem alguns bons motivos técnicos… Para começar, utf-8 é compatível com caracteres ASCII, então para este não é necessária nenhuma conversão. Também, os caracteres unicode (utf8, utf16 e utf32) foram desenvolvidos inicialmente para substituir ASCII e ISO, então é natural que sejam utilizados no lugar destes. Para finalizar, algumas bibliotecas do PHP, e também de outras linguagens, só funcionam com codificação utf-8, tais como json, simpleXML e Soap, assim, utilizando a aplicação toda em utf-8 você evita converter constantemente caracteres de/para a codificação desejada.

Fontes: http://www.cl.cam.ac.uk/~mgk25/unicode.html, http://wilker-dev.com/porque-usar-utf-8-codificandodecodificando

Quanto mais simples melhor

Tags: , — January 20, 2009 @ 9:08 pm

Fazendo manutenção em um script hoje no trabalho (código legado), me deparei com um código mais ou menos assim:

$condicao = !($var == 0);

Devo ter levado cerca de uns 5 minutos para entender o que a maldita expressão retornava. Pelo menos ela rendeu algumas risadas minhas e de meus colegas.

Acontece que, em programação, quanto mais simples e fácil de entender se deixar uma expressão melhor. Mesmo que você seja o único a ter acesso ao fontes posteriormente.

Não quero criticar o autor do código que eu estava mantendo (até porque não sei quem é), mas apenas estou usando o (mau) código acima para exemplificar o tema do tópico.

Falando de boas práticas de programação, não se nega uma comparação deste jeito. O correto seria usar o operador NOT EQUAL (diferente):

$condicao = ($var != 0);

E se considerarmos as facilidades de conversão de tipos do PHP, podemos simplificar ainda mais, bastanto usar um cast:

$condicao = (bool) $var;

Explicando…
A expressão acima (primeiro exemplo) compara se a variável é igual a 0 (zero) e depois nega o resultado, assim se a variável for igual a zero, a comparação retornará true (verdadeiro), que se tornará false (falso) devido a negação (!), o que dá o mesmo resultado que comparar se a variável é diferente de 0 (zero)(segundo exemplo). Como em PHP 0 (zero) é validado com false (falso) e qualquer outro valor como true (verdadeiro), o resultado é o mesmo que simplesmente converter a variável para booleano (terceiro exemplo).

Resumindo, sempre mantenha as linhas de código o mais claras e simples o possível.
Seguem algumas dicas:

  • Evite expressões difíceis de entender, como a do exemplo deste post. Verifique há um modo mais simples de obter o mesmo resultado com código mais claro e/ou menor, se não encontrar, adicione comentário para tornar a expressão mais clara;
  • use nomes de variáveis que exemplifiquem sua finalidade. Prefira usar $cor, ao invés de $c ou $x;
  • sempre indente corretamente seu código, deixando os bloco {} bem visíveis. Use linhas em branco entre blocos de comandos diferentes. Prefira usar espaços ao invés de tabs para indentação, assim o código fica com o mesmo visual em qualquer editor;
  • evite blocos vazios, como um if ou loop sem corpo, é comum encontrarmos blocos como:
    if ($valor == true) {
     
    } else {
        $var = 'constante';
    }
  • utilize phpdoc
    /**
     * Descrição da classe, método ou função
     *
     *@param tipo [variável [descrição]]
     *@return tipo [descrição]
     */

    para definir classes, interfaces, métodos, propriedades e funções. Este é o método de documentação padrão do PHP e auxilia no uso de IDEs especializadas (Eclipse PDT, Zend Studio, etc.);

  • comente TODA linha de código sempre que possível.

Com estas boas práticas, seus códigos deverão ter uma vida útil muito mais longa (sim, código fonte tem validade, e a clareza e documentação destes serve de embalagem).

Só pra concluir, vou colocar uma tabelinha de comparações básicas em PHP aqui, do tipo que a gente sempre fica em dúvida quando usa um if($var) :

//array vazio, string vazia, 0 com ou sem aspas e null
//são todos avaliados como FALSE (falso)
array() == "" == '' == '0' == 0 == null == false;
//se usados operadores de comparação explícita,
//que também comparam os tipos (=== e !==)
//APENAS valores IDÊNTICOS são avaliados
//como TRUE (verdadeiro)
0 === 0;
'abc' === 'abc';
 
//todos diferentes se comparados também em seus tipos
array() !== "" !== '' !== '0' !== 0 !== null !== false;

Compilando Chromium (ou Google Chrome) no Linux

Tags: , , — September 11, 2008 @ 4:13 pm

Com o lançamento beta do navegador web Google Chrome, obviamente eu também fiquei animado e ansioso para testar o novo “brinquedinho”.

Vou mostrar aqui como compilar o Chromium, o projeto no qual é baseado o Google Chrome, no Debian GNU/Linux e rodar os unit tests que vêm com ele. Note que não existe ainda um navegador Chromium para Linux, tudo o que temos são alguns comandos de terminal usados para testar alguns móduilos, ou seja, este tutorial será exclusivamente destinado a desenvolvedores (principalmente C/C++) e pessoas curiosas.

Nota: Ainda não existe uma versão funcional de navegador baseado no Chromium para Linux. Porém, vários sub-módulos podem ser compilados no Linux, mas tudo o que se obtém é um comando executável que retorna “all tests pass”. ”

Se você deseja instalar um navegador baseado no Chromium funcional, procure por um dos vários tutoriais de instalação do Google Chrome no Wine.

Primeiramente, você precisará instalar as seguintes dependencias:

  • Subversion >= 1.4
  • pkg-config >= 0.20
  • Python >= 2.4
  • Perl >= 5.x
  • gcc/g++ >= 4.2
  • bison >= 2.3
  • flex >= 2.5.34
  • gperf >= 3.0.3
  • libnss3-dev >= 3.12

No Debian e distribuições derivadas dele (como o Ubuntu) basta instalar tudo com o apt-get / aptitude:

# aptitude install subversion \
    pkg-config \
    python \
    perl \
    g++ \
    bison \
    flex \
    gperf \
    libnss3-dev

Após instalar as dependências, escolha um diretório para colocar os fontes e compilar. Vou considerar que o diretório escolhido seja $HOME/chromium. Primeiramente crie o diretório e mude para ele:

$ mkdir $HOME/chromium
$ cd $HOME/chromium

Então obtenha o depot tools usando o comando svn:

$ svn co http://src.chromium.org/svn/trunk/depot_tools/linux depot_tools

Como alternativa, você pode baixar o depot tools em tar.gz.

Depois disso mude seus locales para “C” (necessário devido a um bug temporário nos scripts gclient, que interpretam a saída do subversion), e execute ./depot_tools/gclient config:

$ export LANG=C
$ export LANGUAGE=C
$ export LC_ALL=C
$ ./depot_tools/gclient config http://src.chromium.org/svn/trunk/src

O checkout dos arquivos via svn deve demorar algum tempo, dependendo de sua conexão. Caso esteja muito lento você pode também obtar por obter um snapshopt do SVN Checkout.

Após obter os fontes, para compilar execute:

$ cd $HOME/chromium/src/chrome
$ ../third_party/scons/scons.py Hammer

Como o projeto ainda está engatinhando, e os desenvolvedores estão “brincando” com o código, é bem comum que alguma coisa falhe nesta parte. Infelizmente será necessário um mínimo de conhecimento em C/C++ ou outras linguagens utilizadas para seguir adiante. Eu por exemplo, me deparei com alguns erros nos arquivos src/webkit/glue/webframe_impl.h e src/skia/effects/SkCullPoints.cpp, facilmente corrigidos removendo uma declaração typedef e adicionando alguns parênteses a uma condição, respectivamente. Estou postando meus DIFFs para caso alguém tenha o mesmo problema:

webframe_implh.diff
skcullpointscpp.diff

Após a compilação, executáveis criados durante o processo estarão disponíveis em $HOME/chromium/src/chrome/Hammer.

Como mencionado anteriormente, Ainda não existe uma versão funcional de navegador baseado no Chromium para Linux. A única coisa que você pode fazer no momento é executar alguns unittests:

$ cd $HOME/chromium/src/chrome
$ Hammer/base_unittests
$ Hammer/net_unittests

Para quem tiver interesse em colaborar com os esforços para termos um navegador baseado no Chromium para linux, não deixem de acessar a página de desenvolvimento para Linux, com alguns detalhes do desenvolvimento, e uma série de bugs aguardando ajuda.

Desta vez não tem screenshot…
Bem, já que insistem… aí vai um screenshot de um unittest:

chrome_baseunittest.jpg

Fonte: http://dev.chromium.org/developers/how-tos/build-instructions-linux

SpiderMonkey JavaScript Shell – Programando JavaScript em linha de comando

Tags: , , , — March 14, 2008 @ 7:10 pm

Desenvolvedores Web costumam ter grandes problemas para debugar JavaScript. Enquanto programas como a extensão FireBug do Firefox fazem milagres para debugar, o programador ainda precisa colocar sucessivos alert()s para descobrir os valores que suas variáveis assumem em determinados pontos. Certo?

Errado!

Estava pesquisando agora a pouco algumas funções de js no MDC quando fiquei meio curioso com o modo como os exemplos de código eram mostrados e, em especial, de uma função print(). Como no fragmento a seguir:

var names = "Harry Trump ;Fred Barney; Helen Rigby ;";
print(names);
var re = /\s*;\s*/;
var nameList = names.split(re);
print(nameList);

Ora, bolas! Javascript não pode imprimir nada em stdout, então, como pode existir uma função print()?

Então que, pesquisando mais um pouquinho, cheguei ao SpiderMonkey Javascript Shell.

O SpiderMonkey é o mecanismo interpretador de Javascript do Gecko, escrito em C, e utilizado em vários produtos Mozilla, como o Firefox, por exemplo e a boa notícia é que ele provê também um Shell para executar js em linha de comando.

Com isso fica extremamente fácil criar e testar scripts para usar posteriormente. Veja o exemplo a seguir:

diovani@debian-websul:~$ js
js> var frase = 'Hello World!';
js> var tamanho = frase.length;
js> var teste = frase + ' tem ' + tamanho + ' caracteres.';
js> print(teste);
Hello World! tem 12 caracteres.
js>

Para instalar o SpiderMonkey JS Shell no Debian GNU/Linux basta executar o comando:

# aptitude update && aptitude install spidermonkey-bin

Após a instalação, basta executar em um terminal o comando $ js para entrar no Shell interativo:

Para entrar no shell interativo use o comando:
$ js

Para executar os scripts de um arquivo (foo.js) use:
$ js -f foo.js

Para executar os scripts de um arquivo (foo.js) e entrar no shell interativo (muito útil para carregar funções ou bibliotecas) em seguida use:
$ js -f foo.js -f -

Mas mesmo para outras distribuições, e até mesmo Windows, deve ser extremamente fácil instalá-lo. Veja o link abaixo para a Documentação do Javascript Shell e exemplos de uso:

Link: Introdução ao Shell Javascript

Next Page >>>