You are viewing yozhek10nozhek

Заметки натуралиста
PHP4, JSON и русский язык 
21st-Mar-2007 08:16 pm
Default Animal
Условия: сервер под FreeBSD, PHP4, отсутствие модуля json. Админских прав на сервере нет.
Задача: в пхп-скрипте есть объект, свойства которого содержат строки в KOI8-r, некоторые с гиперссылками. Нужно передать этот объект в браузер в виде JSON-объекта.


Решение: исходя из того, что json модулем не доступен, dl() запрещена, будем использовать json-реализацию на PHP. Для начала вооружаемся http://pear.php.net/pepr/pepr-proposal-show.php?id=198.

Всё хорошо, но эта штука не работает с KOI8-r (заявлены ASCII и UTF-8), по крайней мере у меня не работала (установки локали и прочие выходки ни на что не влияли).

Поэтому будем работать с UTF-8. Замечу, что при этом в браузер доходит текст всё-таки в KOI8-r.

Вот, что у меня работает:
$json_output = ’’;
$json_output .= "<script type=\"text/javascript\">\nvar orders = [\n";

while ($row = mysql_fetch_array ($res))
{
   $order = new Order();
      $order->setAuthor ($row[’author’]);
      $order->setFtime ($row[’ftime’]);
      $order->setContent ($row[’content’]);
      $order->setStatus ($row[’status’], $row[’id’], $me);
      $order->setServ ($row[’serv’]);
      $order->setEtime ($row[’etime’]);

   $json = new Services_JSON();
   $json_output .= eregi_replace ("href\=\"([^\"]+)\"", "href=\\\"\\1\\\"", 
                         stripslashes (strtr($json->encode(json_fix_cyr($order)), $u2koi)) .",\n");
}

$json_output = substr ($json_output, 0, -2);
$json_output .= "\n];";

echo $json_output;


Собственно, функция json_fix_cyr() самописная, сделана на основе аналогичной отсюда, но с учетом того, что у меня в неё передается именно объект и всё свойства его — строки (это я знаю заранее, т.к. методы set* делают в общем говоря $this->etime = (string) ...)

function json_fix_cyr($var)
{
   $vars = get_object_vars($var);

   foreach ($vars as $m => $v) {
      $var->$m = iconv(’KOI8-r’, ’UTF-8’, $v);
   }
 
   return $var;
}


Если хорошо присмотреться, в первом примере делается strtr массивом $u2koi, вот он:
$u2koi = array 
(
’\u0430’ => ’а’, ’\u0410’ => ’А’,
’\u0431’ => ’б’, ’\u0411’ => ’Б’,
’\u0432’ => ’в’, ’\u0412’ => ’В’,
’\u0433’ => ’г’, ’\u0413’ => ’Г’,
’\u0434’ => ’д’, ’\u0414’ => ’Д’,
’\u0435’ => ’е’, ’\u0415’ => ’Е’,
’\u0451’ => ’ё’, ’\u0401’ => ’Ё’,
’\u0436’ => ’ж’, ’\u0416’ => ’Ж’,
’\u0437’ => ’з’, ’\u0417’ => ’З’,
’\u0438’ => ’и’, ’\u0418’ => ’И’,
’\u0439’ => ’й’, ’\u0419’ => ’Й’,
’\u043a’ => ’к’, ’\u041a’ => ’К’,
’\u043b’ => ’л’, ’\u041b’ => ’Л’,
’\u043c’ => ’м’, ’\u041c’ => ’М’,
’\u043d’ => ’н’, ’\u041d’ => ’Н’,
’\u043e’ => ’о’, ’\u041e’ => ’О’,
’\u043f’ => ’п’, ’\u041f’ => ’П’,
’\u0440’ => ’р’, ’\u0420’ => ’Р’,
’\u0441’ => ’с’, ’\u0421’ => ’С’,
’\u0442’ => ’т’, ’\u0422’ => ’Т’,
’\u0443’ => ’у’, ’\u0423’ => ’У’,
’\u0444’ => ’ф’, ’\u0424’ => ’Ф’,
’\u0445’ => ’х’, ’\u0425’ => ’Х’,
’\u0446’ => ’ц’, ’\u0426’ => ’Ц’,
’\u0447’ => ’ч’, ’\u0427’ => ’Ч’,
’\u0448’ => ’ш’, ’\u0428’ => ’Ш’,
’\u0449’ => ’щ’, ’\u0429’ => ’Щ’,
’\u044a’ => ’ъ’, ’\u042a’ => ’Ъ’,
’\u044b’ => ’ы’, ’\u042b’ => ’Ы’,
’\u044c’ => ’ь’, ’\u042c’ => ’Ь’,
’\u044d’ => ’э’, ’\u042d’ => ’Э’,
’\u044e’ => ’ю’, ’\u042e’ => ’Ю’,
’\u044f’ => ’я’, ’\u042f’ => ’Я’,

’\r’ => ’’,
’\n’ => ’<br />’,
’\t’ => ’’
);



Вот, собственно, и всё.

Весь этот код выводит примерно такой js в браузер:
<script type="text/javascript">
var orders = [

{"author":"blablabla","ftime":"19 марта, 10:14","content":"testsetestset","status":"В очереди","serv":"Никто","etime":"19 марта, 17:57","concl":""},
{"author":"123123","ftime":"16 марта, 11:21","content":"123123123123","status":"В очереди","serv":"Никто","etime":"16 марта, 18:09","concl":""}

];
</script>


в общем-то, что и нужно было.

Для работы с cp1251 или, тем более, utf8, модификаций нужно минимум.

Может, это уже где-то и реализовано, но либо найти это долго, либо не работает, как написано.

P.S. Lj что-то не особо предназначен для написания в него кода ;)
Comments 
14th-Jun-2007 11:43 pm (UTC)
слушай я случайно нашел эту запись яндексом
у меня сервер утф8, кодировка везде прописана утф8 и заголовки утф8
задаю json-запрос к фликру через XMLHttpRequest
получаю что-то типа "\u042f\u0440\u0443\u0448\u0438\u043d\u043e"
там тоже написано что фликр работает только с утф8

не подскажешь как быть?
мне не надо КОИ или Вин
из родного в родное не могу
15th-Jun-2007 06:46 am (UTC)
Во-первых, уже после того, как я написал это, я где-то находил нормальную функцию перекодирования вот этой ерунды "\u042f\u0440\u0443\u0448\u0438\u043d\u043e" в нормальные символы (самому разбираться некогда, да и не нужно мне).

Во-вторых: а ты не пробовал сделать то, что я тут выложил, только буковки в $u2koi закодировать в UTF'е (скорей всего проканает просто copy/paste отсюда, т.к. lj в UTF вроде) и в функции json_fix_cyr() убрать iconv и оставить просто $var->$m = $v;

А вообще, если можешь, покажи строку запроса на фликр, что там находится (какая конкретно картинка с каким конкретно титлом или что там ещё), может че-то ясней станет (я пользуюсь jabber'ом, можешь кидать туда)
29th-Dec-2007 02:51 pm (UTC)
сенк, помогло в работе!
29th-Dec-2007 08:55 pm (UTC)
здóрово )
7th-Mar-2008 12:37 pm (UTC)
а как на JS преобразовать обратно?
7th-Mar-2008 03:33 pm (UTC)
Что преобразовать обратно?

Цель всех этих потуг - добиться нормальной передачи кириллических данных как json в браузер (ага, когда это было - год назад уже).

Использование указанной в начале библиотеки крайне легко решает задачу собственно, создания json, но не для русского текста, на что и был сделан workaround (в народе - костыль).
25th-Apr-2008 05:30 pm (UTC) - Новый Игровой сайт с кучей интересных фишек
Anonymous
http://YourPokerCash.ru – игра покер онлайн.
Информационный Портал о Покере - здесь вы найдете покер игры, скачаете покер, прочитаете правила покера, а также сможете улучшить свою стратегию игры в
покер. Кроме того, мы предлагаем вам эксклюзивный обзор всех ведущих покер-румов мира.
Наш суппорт центр ответит на все интересующие вас вопросы, а также поможет с решением проблем, которые могут возникнут в выбранных покер комнатах.
This page was loaded Oct 23rd 2014, 10:04 am GMT.