Removendo acentuação no PHP – UTF-8

Introdução

Neste artigo vamos aprender como remover acentos de strings no PHP levando em consideração que a codificação de caracteres utilizada seja UTF-8. UTF-8 é a codificação de caracteres mais utilizada na web atualmente. Portanto, se você chegou neste tutorial, é que esteja utilizando UTF-8 no seu projeto e esteja com problemas de acentuação. Talvez utilizou alguma função pronta na internet e não resolveu o seu problema. Este artigo pode te ajudar.

Reproduzindo e Identificando o problema

Normalmente utilizamos a função strtr() do PHP para realizar as substituições dos caracteres acentuados. Internamente o php trata strings como sequência de bytes sem levar em consideração a codificação de caracteres utilizada. Como o Unicode através do UTF-8 pode utilizar mais de um byte para representar um caracter, e isso acontece com caracteres acentuados, a função strtr() acaba trazendo um resultado indesejado na hora de realizar a substituição.

Entretanto você terá problemas com a função strtr() somente quando utilizar string nos parâmetros. Portanto, de acordo com a implementação do exemplo abaixo, você terá problemas:

<?php

// assume $str esteja em UTF-8
$str = 'eletrônica'; 

$from = "áàãâéêíóôõúüçÁÀÃÂÉÊÍÓÔÕÚÜÇ";
$to = "aaaaeeiooouucAAAAEEIOOOUUC";

echo strtr($str, $from, $to); // corrompe os caracteres acentuados

Simplesmente, utilizar arrays associativos como parâmetros para a função strtr() resolve o problema.
Veja exemplo abaixo:

<?php
// assume $str esteja em UTF-8
$str = 'eletrônica'; 

echo strtr($str, 'ôÔ', 'oO'); // corrompe os caracteres acentuados
echo strtr($str, array('ô' => 'o', 'Ô' => 'O'));  // funciona corretamente

Soluções

Método 1

Como vimos anteriormente, utilizar array associativo como parâmetro para o strstr() resolve o problema.
Portanto, uma implementação segura de substituição de caracteres acentuados pode ser realizada da seguinte forma:
(Lembre-se em configurar o seu IDE/Editor de textos para UTF-8)

<?php
// assume $str esteja em UTF-8
$str = 'eletrônica'; 

// assume $str esteja em UTF-8
$map = array(
    'á' => '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'
);

echo strtr($str, $map); // funciona corretamente

Método 2

Temos uma outra forma de solucionar o problema utilizando expressões regulares. No caso, a solução fica mais enxuta e reutilizável para outras situações.
A solução abaixo é possível devido as funções preg_* do php tem suporte unicode (utf-8)

Baseado em http://stackoverflow.com/questions/1454401/how-do-i-do-a-strtr-on-utf-8-in-php

   <?php

// assume $str esteja em UTF-8
$str = 'eletrônica'; 

// assume $str esteja em UTF-8
$from = "áàãâéêíóôõúüçÁÀÃÂÉÊÍÓÔÕÚÜÇ";
$to = "aaaaeeiooouucAAAAEEIOOOUUC";

echo utf8_strtr($str, $from, $to); // funciona corretamente

function utf8_strtr($str, $from, $to) {
    $keys = array();
    $values = array();
    preg_match_all('/./u', $from, $keys);
    preg_match_all('/./u', $to, $values);
    $mapping = array_combine($keys[0], $values[0]);
    return strtr($str, $mapping);
}

Bônus – Zend Framework 2

Segue abaixo a implementação de um Filter para Zend Framework2 que remove acentuação utilizando o método 2 explicado anteriormente:

<?php
namespace Application\Filter;

use Zend\Filter\FilterInterface;

/**
 * Remove acentuação de uma string
 * @author Douglas.Pasqua
 *
 */
class RemoveAccent implements FilterInterface
{
	public function filter($value)
	{	
		$from = "áàãâéêíóôõúüçÁÀÃÂÉÊÍÓÔÕÚÜÇ";
		$to = "aaaaeeiooouucAAAAEEIOOOUUC";
				
		$keys = array();
		$values = array();
		preg_match_all('/./u', $from, $keys);
		preg_match_all('/./u', $to, $values);
		$mapping = array_combine($keys[0], $values[0]);
		$value = strtr($value, $mapping);
				
		return $value;
	}
}

Conclusão

Qualquer um dos dois métodos utilizados é totalmente válido. O método 2 abre o leque caso precise implementar outras substituições e deixa a implementação mais fácil de manter.

Please follow and like us:

Comments

  1. By Edilberto

    • mm By Douglas V. Pasqua

  2. By Eric

  3. By marco

    • mm By Douglas V. Pasqua

  4. By Christian

    • mm By Douglas V. Pasqua

  5. By Kleyber

    • mm By Douglas V. Pasqua

  6. By Evandro

    • mm By Douglas V. Pasqua

Follow

Get every new post on this blog delivered to your Inbox.

Join other followers: