MySQL – Pesquisa em Registros com Acento com PHP
[ads2]
Muita gente já teve problemas ao fazer consultas no MySQL quando o registro tem algum caractere com acento. Eu já tive, mas consegui resolver com uma alternativa.
Função REGEXP()
Você conhece esta função? REGEXP é uma expressão regular que pode ser usada na otimização de buscas. Ela pode substituir a cláusula LIKE ou a IN, tendo mais opções e sendo assim mais eficiente.
Uma consulta que você faria com vários LIKEs, você pode fazer com apenas um REGEXP. E em relação ao IN é como se fosse um IN potencializado, pois é possivel colocar opções dentro das opções, por exemplo:
Exemplo com IN:
SELECT * FROM USUARIO WHERE NOME IN("Jose","Antonio");
Exemplo com REGEXP:
SELECT * FROM USUARIO WHERE NOME REGEXP("Jose|Antonio");
Mas pera ia, onde está a diferença? É, realmente do jeito que foi mostrado não faz nenhuma diferença, mas vamos supor que em sua tabela você tenha usuários com o nome José, com e sem acento, e então como fará para filtrar isso? É ai que entra uma das vantagens do REGEXP. Veja:
SELECT * FROM USUARIO WHERE NOME REGEXP "Jos(é|e)|Ant(ô|o)nio";
Além disso podem ser usadas também apenas partes dos nomes, mas acho que isso já é suficiente para o objetivo do nosso post.
Agora, imagino que você esteja desenvolvendo um formulário de pesquisa em seu site ou sistema WEB, certo? E provavelmente está usando PHP para fazer a consulta no banco de dados, e então precisa tratar as strings da pesquisa, para que elas fiquem de acordo com o que a função REGEXP trabalha.
Para isso eu desenvolvi uma função PHP que substitui todas as vogais por cláusulas REGEXP e também o “Ç”. Veja:
'a',
'à' => 'a',
'ã' => 'a',
'â' => 'a',
'é' => 'e',
'ê' => 'e',
'í' => 'i',
'ó' => 'o',
'ô' => 'o',
'õ' => 'o',
'ú' => 'u',
'ü' => 'u',
'ç' => 'c',
'Á' => 'A',
'À' => 'A',
'Ã' => 'A',
'Â' => 'A',
'É' => 'E',
'Ê' => 'E',
'Í' => 'I',
'Ó' => 'O',
'Ô' => 'O',
'Õ' => 'O',
'Ú' => 'U',
'Ü' => 'U',
'Ç' => 'C'
);
//Array para REGEXP
$regpx = array(
'a' => '(a|á|á|à|à|â|â|ã|ã)',
'A' => '(a|á|á|à|à|â|â|ã|ã)',
'e' => '(e|é|é|è|è|ê|ê)',
'E' => '(e|é|é|è|è|ê|ê)',
'i' => '(i|í|í|ì|ì|î|î)',
'I' => '(i|í|í|ì|ì|î|î)',
'o' => '(o|ó|ó|ò|ò|ô|ô|õ|õ)',
'O' => '(o|ó|ó|ò|ò|ô|ô|õ|õ)',
'u' => '(u|ú|ú|ù|ù|û|û)',
'U' => '(u|ú|ú|ù|ù|û|û)',
'ç' => '(c|ç|ç)',
'c' => '(c|ç|ç)'
);
//Substituindo acentos
$str = strtr($str, $map);
//Substituindo vogais e ç para REGEXP
$str = strtr($str, $regpx);
//Substituindo espaços em branco
$str = str_replace(' ', '|', $str);
return ($str);
}
?>
Perceba que a primeira coisa que eu faço é substituir as vogais com acentos para vogais comuns sem acento, com a função strtr() do PHP, que retorna uma string cópia da que é passada como primeiro parâmetro, substituindo todas as ocorrências contidas no array passado no segundo parâmetro, simples assim. Depois substituo as vogais por comandos para o REGEXP. Por fim substituo os espaços em branco por “|”, para que se o usuário digitar: “quero pão” a função retorne:
“q(u|ú|ú|ù|ù|û|û)r(o|ó|ó|ò|ò|ô|ô|õ|õ)|p(a|á|á|à|à|â|â|ã|ã)(o|ó|ó|ò|ò|ô|ô|õ|õ)”
Ficou grande né? Maior ainda ficaria se estivesse usando vários likes.
Mas pera ai, como vou fazer para aplicar isso à minha consulta? Simples:
$pesquisa = mysql_query('SELECT * FROM USUARIO WHERW NOME REGEXP "'.trataPesquisa($suaPesquisa).'"');
Pronto pessoal, é isso, qualquer dúvida deixe um comentário que eu terei prazer em responder. Obrigado!
[ads1]
Obrigado esse tutorial me ajudou.