Estou tentando remover acentos de caracteres em string PHP como o primeiro passo para tornar a string utilizável em um URL.
Estou usando o seguinte código:
$input = "Fóø Bår";
setlocale(LC_ALL, "en_US.utf8");
$output = iconv("utf-8", "ascii//TRANSLIT", $input);
print($output);
A saída que eu esperaria seria algo assim:
F'oo Bar
No entanto, em vez de os caracteres acentuados serem transliterados, eles são substituídos por pontos de interrogação:
F?? B?r
Tudo o que posso encontrar online indica que a configuração do local resolverá o problema, mas já estou fazendo isso. Já verifiquei os seguintes detalhes:
- A localidade que estou definindo é compatível com o servidor (incluído na lista produzida por
locale -a
) - As codificações de origem e destino (UTF-8 e ASCII) são suportadas pela versão do servidor de iconv (incluída na lista produzida por
iconv -l
) - A string de entrada é codificada em UTF-8 (verificada usando a
mb_check_encoding
função do PHP , conforme sugerido na resposta de mercator ) - A chamada para
setlocale
foi bem-sucedida (ele retorna em'en_US.utf8'
vez deFALSE
)
A causa do problema:
O servidor está usando a implementação errada de iconv. Possui a versão glibc em vez da versão libiconv necessária .
Observe que a função iconv em alguns sistemas pode não funcionar conforme o esperado. Nesse caso, seria uma boa idéia instalar a biblioteca GNU libiconv. Provavelmente acabará com resultados mais consistentes.
- Introdução do manual de PHP ao iconv
Detalhes sobre a implementação do iconv que é usada pelo PHP estão incluídos na saída da phpinfo
função.
(Não consigo recompilar o PHP com a biblioteca iconv correta no servidor com o qual estou trabalhando para este projeto, então a resposta que aceitei abaixo é a mais útil para remover acentos sem suporte a iconv.)
Respostas:
Acho que o problema aqui é que suas codificações consideram ä e å símbolos diferentes de 'a'. Na verdade, a documentação do PHP para strtr oferece um exemplo para remover acentos da maneira mais feia :(
http://ie2.php.net/strtr
fonte
mb_strstr
é a função errada e não existemb_strtr
E quanto à implementação do WordPress ?
Para entender melhor o que essa função faz, verifique esta tabela de conversão correspondente aqui:
Você mesmo pode gerar essa tabela de convecção simplesmente iterando na
$chars
matriz da função:fonte
Este é um código que encontrei e uso com frequência:
fonte
strtr()
não reconhece multibyte, se o seu arquivo de script estiver codificado em um formato multibyte (por exemplo, UTF-8), esta função produz resultados errados.ů, ž, ř, č, ...
Versão amigável UTF-8 da função simples postada acima por Gino:
Tive que chegar a isso porque meu documento php foi codificado em UTF-8.
Espero que ajude.
fonte
se você tiver http://php.net/manual/en/book.intl.php disponível, isso resolveu seu problema
fonte
Lower()
não é necessário neste casoAo usar
iconv
, o parâmetro locale deve ser definido:Rende em:
Outros locales então cs_CZ e en_US Eu não instalei e não posso testá-lo.
Em C #, vejo a solução usando a tradução para a forma normalizada Unicode - os acentos são separados e, em seguida, filtrados por meio da categoria Unicode sem espaçamento.
fonte
A maneira mais fácil é usar a
iconv()
função nativa do PHP.fonte
echo iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', 'usuario o contraseña incorrectos');
saída muito confiávelusuario o contrase?a incorrectos
setlocale(LC_CTYPE, 'cs_CZ'); echo iconv('UTF-8', 'ASCII//TRANSLIT', "usuario o contraseña incorrectos"); // output: usuario o contrasena incorrectos
. Por favor, consulte a documentação do PHP para mais informações. Está tudo aí! php.net/manual/en/function.iconv.phpNa verdade, é uma questão de gosto. Existem muitos sabores para converter essas letras.
fonte
Você pode usar urlencode. Não faz bem o que você quer (remove os acentos), mas lhe dará uma string utilizável no url
Em Perl, eu poderia usar uma expressão regular traduzida, mas não consigo pensar no equivalente do PHP
etc ...
você poderia fazer isso usando preg_replace
(Observe que isso foi digitado a partir de uma cerveja embaçada montada na sexta-feira após a memória do meio-dia, então pode não estar 100% correto)
ou você poderia fazer uma tabela hash e fazer uma substituição com base nela.
fonte
aqui está uma função simples que normalmente uso para remover acentos:
fonte
Eu concordo com o comentário de georgebrock.
Se você encontrar uma maneira de fazer o // TRANSLIT funcionar, poderá criar URLs amigáveis:
$url = preg_replace( '/(\w)[^\w\s](\w)/', '$1$2', $url );
$url = preg_replace( '/[^a-z0-9]+/', '-', $url );
$url = preg_replace( '-'
por exemplo'/(?:(^|\-)\-+|\-$)/', '', $url );
Se você não conseguir fazer funcionar, substitua setp 1 por strtr / substituição baseada em caracteres, como a solução de Xetius.
fonte
Não consigo reproduzir o seu problema. Obtenho o resultado esperado.
Como exatamente você está usando
mb_detect_encoding()
para verificar se sua string é de fato UTF-8?Se eu simplesmente chamar
mb_detect_encoding($input)
uma versão codificada em UTF-8 e ISO-8859-1 de sua string, ambas retornarão "UTF-8", de modo que a função não é particularmente confiável.iconv()
me dá um "aviso" de PHP quando obtém a string codificada incorretamente e apenas ecoa "F", mas isso pode ser apenas por causa de diferentes configurações / versões de PHP / iconv (?).Eu sugiro que você tente ligar
mb_check_encoding($input, "utf-8")
primeiro para verificar se sua string é realmente UTF-8.Acho que provavelmente não é.fonte
A implementação do Cazuma Nii Cavalcanti foi mesclada com a lista de caracteres do Junior Mayhé, esperando economizar tempo para alguns de vocês.
fonte
Acabei de criar um método removeAccents baseado na leitura deste tópico e deste outro também ( Como remover acentos e transformar letras em caracteres ASCII "simples"? ).
O método está aqui: https://github.com/lingtalfi/Bat/blob/master/StringTool.md#removeaccents
Os testes estão aqui: https://github.com/lingtalfi/Bat/blob/master/btests/StringTool/removeAccents/stringTool.removeAccents.test.php ,
e aqui está o que foi testado até agora:
e converte apenas coisas acentuadas (letras / ligaduras / cédilles / algumas letras com uma linha a / ...?).
Aqui está o conteúdo do método: ( https://github.com/lingtalfi/Bat/blob/master/StringTool.php#L83 )
fonte
No laravel você pode simplesmente usar
str_slug($accentedPhrase)
e se você se preocupar com o traço (-) que este método substitui por espaço, você pode usarstr_replace('-', ' ', str_slug($accentedPhrase))
fonte
str_slug($word, ' ');
Algo assim?
fonte
Se a tarefa principal é apenas usar a string em uma URL, por que não usar o slugyfier ?
então
Ele também tem muitas pontes para estruturas populares. Por exemplo, você pode usar o Doctrine Extensions Sluggable comportamento do para gerar automaticamente um slug exclusivo para cada entidade no banco de dados e usá-lo na URL.
Se você deseja apenas eliminar todos os acentos, pode brincar com conjuntos de regras para satisfazer os requisitos.
fonte
Você pode usar um estilo de chave de matriz => valor para usar com strtr () com segurança para caracteres UTF-8, mesmo se eles forem de vários bytes.
Além disso, você salva a decodificação / codificação na parte UTF-8.
fonte
Uma versão melhorada da
remove_accents()
função de acordo com a formatação da última versão do Wordpress 4.3 é:Minha resposta é uma atualização da solução @dynamic , visto que romeno ou talvez outros diacríticos de idioma não foram convertidos. Escrevi as funções mínimas e funciona perfeitamente.
fonte
fonte
Com base na resposta de @Mimouni, fiz esta função para transliterar strings acentuadas para strings não acentuadas.
fonte
O que há de errado com este? Funciona com UTF8
Pode ser mais rápido não usando
preg_replace
, mas velocidade não era meu objetivo aqui.fonte
Esta resposta eu tenho dicas a seguir aqui, então não é realmente minha. Funciona para mim usando LATIN1 ou UTF-8. Se você usar outros conjuntos de caracteres, provavelmente deve adicioná-los para
mb_detect_encoding
funcionar. Provavelmente também é necessário definir o ambiente correto.fonte
Fóø Bår
, na verdade, só conseguiFo? Bar
. Não foi possívelø
traduzir o caractere parao
. Tentei mudar meu ambiente para no_NO, da_DK, mas não interferiu. Usandosetlocale(LC_CTYPE,'da_DK')
eu tenhoFo? Baar
.Um dos truques que descobri na web foi usar htmlentities e, em seguida, remover o caractere codificado:
Não é perfeito, mas funciona bem em alguns casos.
Mas, você está escrevendo sobre a criação de uma string de URL, então urlencode e sua contraparte urldecode podem ser melhores. Ou, se você estiver criando uma string de consulta, use esta última função: http_build_query .
fonte
A implementação do WordPress é definitivamente a mais segura para strings UTF8. Para strings Latin1, um strtr simples faz o trabalho, mas certifique-se de salvar seu script no formato LATIN1, não UTF-8.
fonte
fonte