Salve!
Hoje entrei em colapso novamente com o famoso problema de encoding do PHP com Mysql.
quem não teve esse problema uma vez na vida atire a primeira pedra!
Resolvi então fazer uma analise completa de possíveis resultados.
Vamos iniciar o teste com 2 bases de dados, uma com encoding em latin1 (default) e outra com utf8_general_ci:
Comandos para criação db test_latin:
CREATE DATABASE test_latin; USE test_latin; CREATE TABLE `table_latin` ( `id` int(11) NOT NULL, `texto` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE `table_utf` ( `id` int(11) NOT NULL, `texto` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Comandos para criação db test_utf:
CREATE DATABASE test_utf; USE test_utf; CREATE TABLE `table_latin` ( `id` int(11) NOT NULL, `texto` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; CREATE TABLE `table_utf` ( `id` int(11) NOT NULL, `texto` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Sendo assim temos todas as possibilidades de tentativas para o teste, agora o próximo passo é crias alguns registros e ver como eles se comportam.
Para isso precisamos criar dois arquivos parecidos em seu conteúdo e com codificações diferentes, um em utf8 (sem BOM) e outro em ISO-8859-1 (ANSI), com o seguinte conteúdo:
Não se preocupe em copiar o código, o download está no final do post.
Arquivo UTF8:
<?php
$db_latin = new mysqli('localhost','root','','test_latin');
$db_utf = new mysqli('localhost','root','','test_utf');
if(!$db_latin){
exit('Erro Conexão Latin: '.$db_latin->error);
}
if(!$db_utf){
exit('Erro Conexão UTF: '.$db_utf->error);
}
/**
* TESTES
* id - Item
* // DB LATIN1
* 1 - Insert padrão TABLE LATIN
* 2 - Insert padrão TABLE UTF
* 3 - Insert TABLE LATIN - UTF8_DECODE
* 4 - Insert TABLE LATIN - UTF8_ENCODE
* 5 - Insert TABLE UTF - UTF8_DECODE
* 6 - Insert TABLE UTF - UTF8_ENCODE
* // DB UTF8_GENERAL_CI
* 7 - Insert padrão TABLE LATIN
* 8 - Insert padrão TABLE UTF
* 9 - Insert TABLE LATIN - UTF8_DECODE
* 10 - Insert TABLE LATIN - UTF8_ENCODE
* 11 - Insert TABLE UTF - UTF8_DECODE
* 12 - Insert TABLE UTF - UTF8_ENCODE
*/
/**
* CONTEUDO
*/
$key = "Órfão";
$key_encode = utf8_encode($key);
$key_decode = utf8_decode($key);
/**
* INSERT LATIN
*/
$query = $db_latin->query("INSERT INTO table_latin (id, texto) VALUES (1, '{$key}');"); // 1 - Insert padrão TABLE LATIN
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_utf (id, texto) VALUES (2, '{$key}');"); // 2 - Insert padrão TABLE UTF
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_latin (id, texto) VALUES (3, '{$key_decode}');"); // 3 - Insert TABLE LATIN - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_latin (id, texto) VALUES (4, '{$key_encode}');"); // 4 - Insert TABLE LATIN - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_utf (id, texto) VALUES (5, '{$key_decode}');"); // 5 - Insert TABLE UTF - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_utf (id, texto) VALUES (6, '{$key_encode}');"); // 6 - Insert TABLE UTF - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
/**
* INSERT UTF
*/
$query = $db_utf->query("INSERT INTO table_latin (id, texto) VALUES (7, '{$key}');"); // 7 - Insert padrão TABLE LATIN
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_utf (id, texto) VALUES (8, '{$key}');"); // 8 - Insert padrão TABLE UTF
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_latin (id, texto) VALUES (9, '{$key_decode}');"); // 9 - Insert TABLE LATIN - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_latin (id, texto) VALUES (10, '{$key_encode}');"); // 10 - Insert TABLE LATIN - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_utf (id, texto) VALUES (11, '{$key_decode}');"); // 11 - Insert TABLE UTF - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_utf (id, texto) VALUES (12, '{$key_encode}');"); // 12 - Insert TABLE UTF - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
?>
Arquivo ISO-8859-1:
<?php
$db_latin = new mysqli('localhost','root','','test_latin');
$db_utf = new mysqli('localhost','root','','test_utf');
if(!$db_latin){
exit('Erro Conexão Latin: '.$db_latin->error);
}
if(!$db_utf){
exit('Erro Conexão UTF: '.$db_utf->error);
}
/**
* TESTES
* id - Item
* // DB LATIN1
* 13 - Insert padrão TABLE LATIN
* 14 - Insert padrão TABLE UTF
* 15 - Insert TABLE LATIN - UTF8_DECODE
* 16 - Insert TABLE LATIN - UTF8_ENCODE
* 17 - Insert TABLE UTF - UTF8_DECODE
* 18 - Insert TABLE UTF - UTF8_ENCODE
* // DB UTF8_GENERAL_CI
* 19 - Insert padrão TABLE LATIN
* 20 - Insert padrão TABLE UTF
* 21 - Insert TABLE LATIN - UTF8_DECODE
* 22 - Insert TABLE LATIN - UTF8_ENCODE
* 23 - Insert TABLE UTF - UTF8_DECODE
* 24 - Insert TABLE UTF - UTF8_ENCODE
*/
/**
* CONTEUDO
*/
$key = "Órfão";
$key_encode = utf8_encode($key);
$key_decode = utf8_decode($key);
/**
* INSERT LATIN
*/
$query = $db_latin->query("INSERT INTO table_latin (id, texto) VALUES (13, '{$key}');"); // 13 - Insert padrão TABLE LATIN
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_utf (id, texto) VALUES (14, '{$key}');"); // 14 - Insert padrão TABLE UTF
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_latin (id, texto) VALUES (15, '{$key_decode}');"); // 15 - Insert TABLE LATIN - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_latin (id, texto) VALUES (16, '{$key_encode}');"); // 16 - Insert TABLE LATIN - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_utf (id, texto) VALUES (17, '{$key_decode}');"); // 17 - Insert TABLE UTF - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
$query = $db_latin->query("INSERT INTO table_utf (id, texto) VALUES (18, '{$key_encode}');"); // 18 - Insert TABLE UTF - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_latin->error . __LINE__);
}
/**
* INSERT UTF
*/
$query = $db_utf->query("INSERT INTO table_latin (id, texto) VALUES (19, '{$key}');"); // 19 - Insert padrão TABLE LATIN
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_utf (id, texto) VALUES (20, '{$key}');"); // 20 - Insert padrão TABLE UTF
if(!$query){ exit('Erro Query: '. $db_utf->error . __LINE__); }
$query = $db_utf->query("INSERT INTO table_latin (id, texto) VALUES (21, '{$key_decode}');"); // 21 - Insert TABLE LATIN - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_latin (id, texto) VALUES (22, '{$key_encode}');"); // 22 - Insert TABLE LATIN - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_utf (id, texto) VALUES (23, '{$key_decode}');"); // 23 - Insert TABLE UTF - UTF8_DECODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
$query = $db_utf->query("INSERT INTO table_utf (id, texto) VALUES (24, '{$key_encode}');"); // 24 - Insert TABLE UTF - UTF8_ENCODE
if(!$query){
exit('Erro Query: '. $db_utf->error . __LINE__);
}
?>
Lembre-se de salvar o arquivo com o encoding diferente para que os testes tenham mais precisão, no teste eu salvei como insert.php (UTF8) e insert_iso.php(ANSI).
Executando os 2 os resultados das tabelas foi esse:
| `test_utf`.`table_utf` | |
|---|---|
| id | texto |
| 8 | Órfão |
| 11 | Órfão |
| 12 | Órfão |
| 20 | Órfão |
| 23 | ?rf?o |
| 24 | Órfão |
| `test_utf`.`table_latin` | |
|---|---|
| id | texto |
| 7 | Órfão |
| 9 | Órfão |
| 10 | Órfão |
| 19 | Órfão |
| 21 | ?rf?o |
| 22 | Órfão |
| `test_latin`.`table_latin` | |
|---|---|
| id | texto |
| 1 | Órfão |
| 3 | Órfão |
| 4 | Órfão |
| 13 | Órfão |
| 15 | ?rf?o |
| 16 | Órfão |
| `test_latin`.`table_utf` | |
|---|---|
| id | texto |
| 2 | Órfão |
| 5 | Órfão |
| 6 | Órfão |
| 14 | Órfão |
| 17 | ?rf?o |
| 18 | Órfão |
O mais incrível é isso, em TODAS as tabelas os resultados são os mesmos, esses testes foram feitos no Windows 7 com XAMPP, se alguem obter resultados diferentes em outros OS ou no Windows mesmo, me informe que eu atualizo o post.
Eu prefiro utilizar nos meus projetos sempre arquivos como UTF-8 assim como o DB, então a solução é aderir ao utf8_decode em inserts.





























