terça-feira, 25 de setembro de 2007

Problema de acentuação com PHP e JSON

Hoje estava trabalhando em uma aplicação com AJAX e me deparei um com problema de acentuação no retorno de alguns dados via JSON do MySQL.
Se em algum campo tiver a palavra "Éramos", por exemplo, ao executar um encode (utilizei a Services_JSON provida pelo PEAR), ele retornará algo como \u0072amos que será renderizado como "ramos".
Depois de googlar sobre o assunto, descobri uma maneira de evitar esse problema.
Considere que o código abaixo é um PHP que retorna dados no formato JSON

<?php
header('Content-type: application/json charset=iso-8859-1');

/*
* codigo para conexao no banco e enviar consulta
* ...
*/

while($row = fetch()){
array_walk($row, 'toUtf8');
$data[] = $row;
}

/*
* codigo para terminar de montar o array de retorno dos dados
*/

require_once('JSON.php');
$json = new Services_JSON();
echo
$json->encode($returnValue); // Instead of json_encode


function toUtf8(&$item, $key) {
$item = iconv("iso-8859-1","utf-8",$item);
}

O segredo está aqui:
$item = iconv("iso-8859-1","utf-8",$item);

O fato de converter todas strings para utf-8 utilizando a iconv, garantiu que meus dados fossem renderizados corretamente.

Por hoje é isso!
Abraços.

8 comentários:

Unknown disse...

Olá,

Acabei de responder seu comentário em meu blog a respeito desse problema.

A questão é que existe algum arquivo que não está utilizando a codificação UTF-8.

Você definindo no JS que vai utilizar ISO já resolveria, ou então as funções utf8_encode/utf8_decode também. São soluções sujas, mas funcionam.

Procure dar uma lida a respeito desse charset, parece coisa de outro mundo no início, mas logo verá que não é nada demais!

Abraço!

Anônimo disse...

salvo meu dia...
vlw

Jape Ntaca disse...

Muchas Gracias ! ! !

Unknown disse...

Estou tentando fazer um autocomplete utilizando token-input.js e JSON, quando me deparei com o JSON retornando null para todos os nomes que estão acentuados. Pelo que vi meu banco é utf-8, minhas páginas (html) estão como iso8859-1. Já coloquei tudo como um ou como outro, inclusive na chamada do script, mas não deu certo. Alguma dica?
Um exemplo:
[{"id":"14","name":"Aparecida"},{"id":"5","name":"Arcebispo..."},{"id":"7","name":null},{"id":"1","name":"Carlos Romel Pereira da Silva"},{"id":"9","name":null},{"id":"2","name":null},{"id":"3","name":"Mauricio Silva Domingos"},{"id":"12","name":null},{"id":"10","name":"Osasco"},{"id":"17","name":"Praia da Joaquina"},{"id":"19","name":"Praia do Centro"},{"id":"18","name":"Praia Mole"},{"id":"20","name":"Regional Centro Oeste"},{"id":"21","name":"Regional Nordeste"},{"id":"22","name":"Regional Norte"},{"id":"23","name":"Regional Sudeste"},{"id":"24","name":"Regional Sul"},{"id":"4","name":"Rodrigo Teixeira Vasconcelos"},{"id":"8","name":null},{"id":"25","name":"Secretariado Nacional"},{"id":"15","name":"Serra Negra"},{"id":"13","name":"Sorocaba"}]

Anônimo disse...

Ja testou com maiusculas acentuadas?

Frank disse...

Amigo, essa foi genial...como eu procurei por uma solução pra ero de chartset no json, e essa tua solução do "$item = iconv("iso-8859-1","utf-8",$item);", é sensacional, resolvel na hora meu problema...
Muito grato, por publicar esse pequeno tutorial que me ajudou bastante.
Um abraço

lminervino disse...

Olá,
Deparei-me com o mesmo problema e logo verifiquei que as diferenças entre "charset" estavam impedindo que o retorno tivesse sucesso.
Bem, aí vai uma solução bem rápida:

/*------------------------------*/
foreach($vetor as $chave => $valor){
$vetor[$chave]=utf8_encode($valor);
}
echo json_encode($vetor);
/*------------------------------*/

Abraço a todos.
Bom desenvolvimento.

marcos herenadez disse...

salvo meu dia... Gracias desde venezuela