пятница, января 19, 2007

Кириллица и php_json

Поддержка UTF-8 в PHP весьма слабая, то же касается и кириллицы. Начав использовать javascript-библиотеку Prototype и AJAX я столкнулся с тем, что модуль php_json, который включен в PHP с версии 5.2.0 (для остальных доступен в виде extension), категорически отказывается воспринимать русский язык. Кириллица просто вырезается.

Дело в том, что php_json обрабатывает только ISO-8859-1, а остальные символы отбрасывает. Функция utf8_encode() тоже не подходит из-за того, что неправильно определяет код символа. Например, русская буква "а" имеет код \u0434, а utf8_encode() кодирует ее как \u00e4. В итоге - на странице кракозябры.

Положение спасает iconv(): iconv('cp1251', 'utf-8', $string). Преобразование корректное. Но, к сожалению, это исключает использование функции json_encode() "как есть" - придется написать свою функцию json_safe_encode() для кодирования данных в формат JSON:
function json_safe_encode($var)
{
return json_encode(json_fix_cyr($var));
}

function json_fix_cyr($var)
{
if (is_array($var)) {
$new = array();
foreach ($var as $k => $v) {
$new[json_fix_cyr($k)] = json_fix_cyr($v);
}
$var = $new;
} elseif (is_object($var)) {
$vars = get_object_vars($var);
foreach ($vars as $m => $v) {
$var->$m = json_fix_cyr($v);
}
} elseif (is_string($var)) {
$var = iconv('cp1251', 'utf-8', $var);
}
return $var;
}

PS.
На www.json.org масса полезных ссылок.

UPD 2008-02-06: $vars = get_object_vars($var); instead of $vars = get_class_vars(get_class($var));. Thanks to Pascal Martineau

16 комментариев:

Pasha комментирует...

БОЛЬШОЕ спасибо!
воспользовался Вашей функцией в своем проекте

Nikita комментирует...

Огромный фэнкс ;-)

Анонимный комментирует...

Спасибо!=)

Анонимный комментирует...
Этот комментарий был удален администратором блога.
jMas комментирует...

Спасибо большое! Эта функция очень выручила меня!!!

Анонимный комментирует...

Огромное спасибо, два дня с кодировками мучался, выручил.

Gruz комментирует...

Велике дякую.

assikilo aka ася комментирует...
Этот комментарий был удален администратором блога.
Анонимный комментирует...

Спасибо!

Анонимный комментирует...

Спасибо огромное. Решил проблему с кириллицей в FancyUpload.

clockworkbird комментирует...

Спасибо, комрад, сохранил мне несколько часов жизни )

Ivan комментирует...

Большое спасибо за этот пост.

Dmitriy комментирует...

Респект чуваку!!! Молоток! Такого гимора лишил! Я три часа мучался с одним кодом, пока не понял, что проблема с кодировкой и тут нашел эту функцию. МолотоК!

Подсказка для других пользователей.
Использование функции очень простое, копируете эти функции в php-файл, потом надо заменить в вашем исходнике слово "json_encode" на "json_safe_encode". И все.

vexdex комментирует...

Спасибо. Это решило мою проблему. С вашего разрешения (надеюсь) я использую этот метод в неизменном виде у себя.

Snick комментирует...

2vexdex: да, конечно, используйте. Оставьте только в комментариях ссылку на этот пост.

Владимир Хорев комментирует...

Спасибо. Ваше решение оказалось СУПЕР
Даже в 2015