Você precisa entender que há várias camadas em que a codificação é utilizada, logo para usar corretamente o UTF-8 é recomendado usar UTF-8 em tudo...
Veja onde podemos informar a codificação de um texto:
- Cabeçalho HTTP Header -
Content-Type: text/html; charset=utf-8
; - Cabeçalho XML -
<?xml version="1.0" encoding="utf-8" ?>
- Cabeçalho HTML -
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
- Cabeçalho XHTML -
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
O cabeçalho HTTP, pode ser informado pelo próprio PHP ou pelo Apache através da seguinte linha no .htaccess:
AddDefaultCharset UTF-8
Agora onde que um servidor PHP com MySQL trata de codificações:
- O próprio código do PHP;
- A conexão PHP MySQL;
- O armazenamento dos dados no MySQL;
Para deixar a conexão do mysql basta usar:
mysql_set_charset('utf8',$link);
O uso de SET NAMES não é recomendado nas versões novas do PHP e MySQL...
Já o armazenamento do MySQL a mudança é feita na hora de criar o banco de dados ou a tabela com o
CHARACTER SET utf8;
Lembrando que o armazenamento MySQL não precisa ser obrigatoriamente em UTF-8, uma vez que podemos definir na conexão qual charset desejamos, é possível que a conexão seja UTF-8, mas o MySQL armazene em Latin1, não sendo do tipo BLOB o campo, o MySQL faz a conversão do charset...
Um dos problemas de usar UTF-8 no PHP é que algumas funções falham ao executar comandos com o strtoupper e o strtolower, que em palavras acentuadas, deixa as letras acentuados sem alteração.
Outro problema que pode ocorrer é quando o usuário usa um editor ISO-8859-1 para um site UTF-8, o código gerado precisa do utf8_encode...
Outro problema é quando o arquivo php é Latin1 e a conexão do banco de dados é UTF-8, e o usuário tenta substituir um texto no php, palavras acentuadas não são substituidas, porque a função procura por um caracter Latin1, enquanto a string do banco de dados venho com caracteres UTF-8....
Outro problema é quando o usuário exagera e usa vários utf8_encode....
Outro problema é usar htmlentities em uma string UTF-8... Deve se usar htmlspecialchars...
Outro problema, mas esse eu preciso confirmar é que no Javascript ao postar uma string, deve-se usar encodeURIComponent e não escape ou encodeURI...
Tomando esses cuidados, metade dos problemas dos programadores PHP desaparecem, e 80% dos problemas de usuários reclamando de letras estranhas também...
Nota: Latin1 é o ISO-8859-1 no MySQL por isso as vezes falo ele...
Sites:
http://www.w3.org/TR/2007/NOTE-i18n-html-tech-lang-20070412/
http://www.w3.org/International/tests/#lang-decl