1 заметка с тегом

wddx

WDDX в PHP и русские символы

У меня ощущение, что никто никогда не пробовал гонять национальные символы через WDDX из PHP в другие языки и обратно. Задача: получить от демона Perl сериализованные данные и десериализовать их. Был выбран формат WDDX, вроде как хорошо описанный стандарт и всё такое. JSON сначала не подошёл, модуль в Perl что-то там дурил, теперь мы это победили. Тем временем в WDDX…

Всё было хорошо, пока в utf8-потоке от Perl не появились символы, которые не влезают в нижнюю половину ASCII. Я перебрал автоматом все кодировки, которые знает iconv, чтобы посмотреть в какой кодировке PHP WDDX умеет есть русские буквы. Ничего ему не понравилось. Потом я догадался сериализовать utf-8 символ через функцию из PHP. Получилось что-то странное. Залез в исходники.

В общем, оказалось, что какое-то время назад кто-то постил баг по этому поводу — UTF-8 в WDDX не передавались вообще. Решили проблему очень просто — взяли кодировку как однобайтовую ISO-8859-1, закодировали в utf-8 и в таком виде выпустили в свет. При получении делается обратное преобразование:

if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) {
    char *decoded;
    int decoded_len;
    decoded = xml_utf8_decode(atts[i], strlen(atts[i]), &decoded_len, "ISO-8859-1");
    stack->varname = decoded;
    break;
}

Соответственно, когда PHP получает из Perl нормальный UTF-8, он его пытается рассмотреть как UTF-8, который надо превратить в ISO-8859-1, на выходе мы получаем вопросы. Чтобы этого не происходило перед wddx_deserialize надо сделать iconv(’iso-8859-1’, ’utf-8’, $string), что решает проблему.

В итоге, мы перешли на JSON. Всем хорошего дня.