Captcha – Confirmação Visual

Depois de um bom tempo com o blog parado, vou voltar explicando um modo de desenvolver um captcha utilizando a biblioteca GD do php. O captcha é um teste de turing reverso, pois é a máquina que  testa se o usuário é humano. Este teste evita que sistemas automatizados enviem spans pelos formulários de seu site.
A idéia é bem simples. Vamos ter um arquivo php que gera uma imagem, podendo ser exibido como se de fato fosse uma imagem:

<img src=”geraImagemConfirmacao.php” alt=”Captcha” />

Essa imagem será gerada, e o conteúdo gravado em um cookie. Este cookie será utilizado na ação de seu formulário, quando deverá ser comparado com o texto digitado pelo usuário. Vou procurar fazer o mais simples possível:

<form action=”acaoConfirmaCodigo.php” method=”post”><img src=”geraImagemConfirmacao.php” alt=”Captcha” />
<input name=”palavraUsuario” type=”text” />

<input type=”submit” />

</form>

Salve este arquivo com um nome qualquer.

No arquivo acaoConfirmaCodigo.php, coloque algo do tipo:

<?php

$palavraUsuario = strtolower($_POST['palavraUsuario']);
$palavraGerada = strtolower($_COOKIE['palavraGerada']);

if($palavraUsuario == $palavraGerada)
echo “Confirmação visual correta.”;
else
echo “Por favor, tente novamente.”;
?>

O que este arquivo faz nada mais é do que pegar a palavra digitada pelo usuário (enviada pelo POST) e a palavra armazenada no cookie, passando ambas para a forma minúscula, e então  comparando-as.

Agora vamos à parte realmente interessante, o arquivo geraImagemConfirmacao.php:

<?php

$larguraImg = 100;
$alturaImg = 30;

$espacoMinLetrasX = 15;
$espacoMaxLetrasX = 20;

$espacoMinLetrasY = 5;
$espacoMaxLetrasY = 10;

$numLetras = 4;

$letras = array(‘2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘Z’, ‘K’, ‘M’, ‘X’);

// cria uma imagem
$imagem = imagecreate($larguraImg, $alturaImg);

/* Cores para utilizar na imagem imagem */
$cinza = imagecolorallocate($imagem,0xF8,0xF8,0xF8);
$cinza_escuro = imagecolorallocate($imagem,0xAC,0xAC,0xAC);
$vermelho = imagecolorallocate($imagem,0xFF,0×00,0×00);
$azul = imagecolorallocate($imagem,0×0F,0×93,0xFF);
$verde = imagecolorallocate($imagem,0×00,0×66,0×00);
$preto = imagecolorallocate($imagem,0×00,0×00,0×00);
$laranja = imagecolorallocate($imagem,0xFF,0×8C,0×24);

$cores = array($vermelho, $azul, $verde, $preto);

$tamanho_letras = count($letras)-1;
$tamanho_cores = count($cores)-1;

/* Escrevendo as letras… */
$palavraGerada = ”;
$x = 0;

for($i=0;$i<$numLetras;$i++){

$x += rand($espacoMinLetrasX, $espacoMaxLetrasX); //localizacao horizontal
$y = rand($espacoMinLetrasY, $espacoMaxLetrasY);

$j = rand(0,$tamanho_cores);

$k = rand(0,$tamanho_letras);
$palavraGerada .= $letras[$k];

imagestring($imagem, 5, $x, $y, $letras[$k], $cores[$j]); //escreve a letra na imagem
}

setcookie(‘palavraGerada’, $palavraGerada, time()+7200);

header(“Content-type: image/jpeg”);
imagejpeg($imagem);
imagedestroy($imagem);
?>

A primeira parte é apenas para configurar a imagem que será gerada:

$larguraImg = 100;
$alturaImg = 30;

Note que essas dimensões têm que ser compatíveis com a quantidade de letras e o espaçamento das letras que você deseja gerar, caso contrário algumas letras ficarão fora da imagem simplesmente por falta de espaço.

$espacoMinLetrasX = 15;
$espacoMaxLetrasX = 20;
$espacoMinLetrasY = 5;
$espacoMaxLetrasY = 10;
$numLetras = 4;

Aqui são determinados os intervalos das posições das letras na imagem. Por exemplo, a posição horizontal (espaço entre as letras) irá variar de 15 a 20px. Para realizar essa variação, utilizamos a função rand(min, max) do php.
E também aqui é determinada a quantidade de letras que serão geradas na imagem.

$letras = array(‘2′,’3′,’4′,’5′,’6′,’7′,’8′,’9′, ‘A’, ‘B’, ‘C’, ‘D’, ‘E’, ‘Z’, ‘K’, ‘M’, ‘X’);

Esse array contém as letras que poderão ser sorteadas e aparecer na imagem. Procure evitar letras como O, I, L… e os números 0 e 1, pois podem ser confundidos com facilidade.

// cria uma imagem
$imagem = imagecreate($larguraImg, $alturaImg);

/* Cores para utilizar na imagem imagem */
$cinza = imagecolorallocate($imagem,0xF8,0xF8,0xF8);
$cinza_escuro = imagecolorallocate($imagem,0xAC,0xAC,0xAC);
$vermelho = imagecolorallocate($imagem,0xFF,0×00,0×00);
$azul = imagecolorallocate($imagem,0×0F,0×93,0xFF);
$verde = imagecolorallocate($imagem,0×00,0×66,0×00);
$preto = imagecolorallocate($imagem,0×00,0×00,0×00);
$laranja = imagecolorallocate($imagem,0xFF,0×8C,0×24);

$cores = array($vermelho, $azul, $verde, $preto);

Neste ponto, criamos a imagem, e associamos as cores que utilizaremos na imagem. Além disso, coloco no array $cores as cores que serão sorteadas para cada letra. (Note mais uma vez que você deve facilitar a vida do usuário, então utilize cores fortes nas letras).

$palavraGerada = ”;
$x = 0;
for($i=0;$i<$numLetras;$i++){

$x += rand($espacoMinLetrasX, $espacoMaxLetrasX); //localizacao horizontal
$y = rand($espacoMinLetrasY, $espacoMaxLetrasY);

$j = rand(0,$tamanho_cores);

$k = rand(0,$tamanho_letras);
$palavraGerada .= $letras[$k];

imagestring($imagem, 5, $x, $y, $letras[$k], $cores[$j]); //escreve a letra na imagem
}

Aqui é onde acontece toda a mágica. É executado um laço, com o for varrendo a quantidade de letras de sua imagem, e para cada letra sortea-se a posição x e y, dentro do intervalo configurado. Note que o intervalo x deve ser incrementado a cada iteração, caso contrário todas as letras ficariam dentro de um mesmo intervalo na horizontal (experimente trocar o += por =, para ver como fica).

Também são sorteadas a letra e sua cor, dentro do array pré-determinado. Só então a letra é gravada na imagem, com a função imagestring() do php.

setcookie(‘palavraGerada’, $palavraGerada, time()+7200);

header(“Content-type: image/jpeg”);
imagejpeg($imagem);

Finalmente a imagem é gravada no cookie e criada na tela, utilizando o cabeçalho Content-type: image/jpeg. Pronto!

Se achar conveniente, você pode utilizar outras funções da GD como imagearc, imagelin.. para “dificultar” a visualização da imagem (cuidado para não deixar a imagem imcompreensível). Pode também utilizar outra fonte para as letras, outra cor de fundo na imagem..

3 Comments

URLs Amigáveis – .htaccess

Urls amigáveis são as urls “semânticamente corretas”; possuem um sentido e são compreensíveis a usuários leigos. Além da vantagem estética, as urls amigáveis ajudam as máquinas de busca na indexação, e são interessantes no sentido de “esconder” a tecnologia que está sendo utilizada.

Por exemplo:
www.meusite.com.br/exibeFotos.php?idAlbum=2&idFoto=35

Nesta url, vê-se que seu site utiliza o php, além de serem exibidas explicitamente duas variáveis GET.

Com a url amigável, você poderia deixar:
www.meusite.com.br/exibeFotos/2/35

Vou explicar aqui um modo de fazer, utilizando o arquivo .htaccess e php.

O .htaccess é um arquivo do apache, utilizado por exemplo para dar permissão de acesso à pastas do servidor. No nosso caso, ele será o “tradutor” das urls.

O .htaccess não transforma a url comum em url amigável. Ao contrário, traduz a url amigável em url “normal”. O que ele faz basicamente é ler a url do browser do usuário (a url amigável), enviada na forma de requisição para o servidor web, e tenta “casar” a url com uma séria de regrinhas. Ao encontrar uma regra que se encaixa com a url, ela traduz para o termo correspondente, ou seja, a url normal. E é esta url que é enxergada pelo php no servidor.

Crie, ou se já existir, edite o .htaccess da pasta raiz de seu site. (sugiro que leiam um pouco sobre o .htaccess antes de prosseguir). No seu .htaccess ficarão as regras de reescrita, ou rewrite rules.

OBS: lembre-se de ativar o mod rewrite no seu servidor, para que as regras funcionem.

Vamos ao nosso .htaccess. Para que nosso exemplo funcione, coloque o seguinte:

RewriteEngine on
RewriteRule ^exibeFotos/([0-9]+)\/([0-9]+)\/?$ exibeFotos.php?idAlbum=$1&idFoto=$2

Pronto! Não vou explicar as expressões regulares, mas vamos tentar entender o que foi feito:

“RewriteRule ^” inicia uma regra de reescrita. Tudo o que aparece do “^” até o “$” é uma expressão regular. É essa expressão que deverá casar com a url amigável que você utilizará em seu site.

Comparem a url com a expressão regular. No nosso caso, nossa url é a seguinte:
www.meusite.com.br/exibeFotos/2/35
exibeFotos/([0-9]+)\/([0-9]+)\/

Nossa url possui a string “exibeFotos”, seguidos de dois números. Como a url casa corretamente com a regra, o endereço será convertido na segunda parte:
exibeFotos.php?idAlbum=$1&idFoto=$2

Basicamente é isso. Não vou explorar mais como fazer as regras de reescrita. Agora vamos às implicações sobre o site.

Se seu site já estava pronto, você deverá substituir TODAS os links de seu site pelas novas urls. Por exemplo, se você tiver um link na sua pagina da seguinte forma:

<a href=”xxxx.php?id=23&x=5”>Ir</a>

Você deverá trocar pela correspondente url amigável. Isso parece idiota, mas muita gente tem dificuldade de entender que o .htaccess não vai transformar as url do seu site. É você que deve fazer isso manualmente. Ele apenas pegará essa nova url e traduzirá para a url normal.

Outro ponto que dará bastante trabalho: suponha que sua url ficou da seguinte forma:
www.meusite.com.br/exibeFotos/2/35
e que seu .htaccess está traduzindo corretamente essa url.

Então para a parte da aplicação que roda no servidor está tudo bem. O php receberá todas as referências do arquivo corretamente. Mas o html é interpretado no browser do usuário. Isso quer dizer que o browser não saberá interpretar corretamente as referências de arquivos, pois não sabe que suas regras de reescrita existem.

Resumindo, isso acontecerá com todos as suas referências no html à imagens, arquivos css e arquivos de mídia.

Por exemplo, se você chama a imagem: <img src=”img/teste.jpg” /> no seu arquivo exibeFotos.php, o browser interpretará sua url amigável como um monte de pastas. Então ele irá procurar a imagem que você colocou na seguinte pasta no servidor:
exibeFotos/2/35/img/teste.jpg, e não encontrará o arquivo.

Uma forma de resolver isso é colocando as referências absolutas, ou seja, a url completa. No nosso caso:
<img src=”http://www.meusite.com.br/img/teste.jpg” />

Para fazer isso de forma a não comprometer seu site, fazendo-o dependente do domínio, sugiro um código simples em php para pegar a url correta:

<?php
$server = $_SERVER['SERVER_NAME'];
$urlPrincipal = “http://”.$server.”/”;
?>

Nas suas referências, coloque:

<img src=”<?=$urlPrincipal?>img/teste.jpg” />

Pronto. Algumas referências:
http://forum.imasters.uol.com.br/index.php?showtopic=203965

http://www.vivaolinux.com.br/dica/Utilizando-URL-Amigavel-no-Apache

4 Comments

Refatoração

Refatoração é a técnica ou um processo no qual melhora-se a parte não funcional de um sistema sem alterar seu comportamento funcional. Quê? Vamos por partes..
Quantas vezes (digo isso por experiência própria) temos que fazer sistemas, ou mesmo criar um módulo para um sistema, e você escuta a célebre expressão: “é pra ontem” ? Não digo que o sistema ficará uma droga, ou que não funcionará, mas o código ficará pobre: trechos duplicados, má indentação, métodos longos, de difícil entendimento. Enfim, o tempo que seria gasto para fazer o trabalho “bem feito”, será gasto quando o sistema necessitar de manutenção/alteração.
É aí que pode entrar a refatoração. Um sistema bem feito, de código limpo e com métodos que “generalizam” a funcionalidade pode ser reaproveitado posteriormente para outros sistemas que necessitem dessas mesmas funcionalidades. A idéia seria, após o sistema ser entregue dentro do prazo exigido, voltar com o projeto para a linha de produção. Os programadores revisam todo o código, retirando as “impurezas” e deixando um código limpo, buscando um melhor desempenho e generalizando ao máximo os métodos.
Situações em que refatorar é interessante:
1- Quando você tem que adicionar uma funcionalidade a um programa e o código do programa não está estruturado de uma forma que torne a implementação desta funcionalidade conveniente, primeiro refatore de modo a facilitar a implementação da funcionalidade e, só depois, implemente-a.
2- Quando se implementa uma nova funcionalidade às pressas, refatore e transforme essa funcionalidade em um módulo, para reaproveitamento em outros sistemas.
3- O código foi tão “porcamente” escrito, que dois meses após o desenvolvimento, se o projeto retornar para manutenção, nem mesmo a equipe que desenvolveu consiguirá compreender a lógica de negócio. Então, antes que o projeto perca o foco dos desenvolvedores, refatore.

Alguns indícios que sugerem a refatoração (retirados da wikipedia):
- Código duplicado (duplicated code)
- Método longo (long method)
- Classe grande (large class)
- Lista de parâmetros longa (long parameter list)
- Má indentação(Bad Indentation)

Links sobre o assunto:
Wikipedia
Martin Fowler – Refactoring
Métodos Ágeis – devagil.wordpress.com

,

No Comments