Исторически сложилось, что мой фреймворк работает не просто на системах с разными кодировками (utf-8, windows-1251, koi8-r), но нередко в смешанных условиях (БД отдаёт данные в utf-8, клиент должен получить в windows-1251, файлы лежат в koi8-r, клиент получает в utf-8, контент сайта отдаётся в koi8-r, но RSS отдаюься в utf-8 и т.п. сочетания).
До какого-то момента всё было прекрасно:
1. Все тексты в PHP-коде лежат в utf-8, но при загрузке система переводит их во внутреннюю кодировку системы. Например:
class ... function title() { return ec("Тест"); }
где ec() - функция, осуществляющая перекодировку utf8->internal_charset
2. Все операции над текстом (upper/lower/substr/etc) осуществляются во внутренней кодировке сервера.
3. При выводе происходит преобразование internal_charset -> output_charset.
4. При загрузке данных из пользовательских файлов происходит перекодировка files_charset -> internal_charset
5. При загрузке данных из БД происходит перекодировка db_charset->internal_charset.
6. Все Smarty-шаблоны в utf-8 и при их загрузке перекодируются в internal_charset.
Всё прекрасно работало, пока мне не потребовались шаблоны на чистом PHP. Ну, с логикой всё понятно. Класс готовит блок данных. При рендеринге система распаковывает их в область видимости и делает include() нужному шаблону, перехватывая вывод. Потом использует результат.
И вот тут у меня случится первый затык. Для простоты рассмотрим конкретный пример.
Пусть internal_encoding, кодировка системы, у нас koi8-r. PHP-шаблон, единообразия ради, в utf-8. Без всякого преобразования сразу же получается каша: в utf-8 текст в PHP вставляются koi8-r данные.
Дальше я сделал очевидно, но не для меня тогда, неверное решение. Я волюнтаристски принял, что internal_encoding всегда utf-8. Плюсы были налицо: отпадает надобность в ec("") функциях, так как internal всегда такой же, как у основных шаблонов. В Smarty в {file...} или {include...} вместо своего типа файлов xfile:// [загрузчик которых которых наряду с прочим занимался перекодировкой] можно использовать обычные файлы, без замечания вставляются PHP-шаблоны. И, вообще, приятно жить в хоть как-то унифицированном мире :)
Понятно уже, где всплыл костыль? internal_charset != системной локали PHP. Не работают strtolower/strtoupper/substr...
И вот я теперь стою на перепутье. И прошу советов, как это можно разгрести :)
Первый вариант вижу лобовой. Сейчас частично ситуацию разруливаю им. Ввводим понятие системной кодировки. Т.е. системной локали. Меняем все strtolower() на свою u_lower(), где делаем iconv из внутренней кодировки фреймворка в системную, потом strtolower и обратно во внутреннюю. Плюсы - остаётся унифицированная кодировка фреймворка. По-прежнему нет надобности в ec(). Возможна более тонкая настройка на системах со глючными mb_string и т.п. Минусы - использование своих функций вместо стандартных. Лишняя нагрузка процессора. Небольшая, но если это будет где-то глубоко в цикле?
Второй вариант. internal_charset всегда равен системной локали, в общем случае не равен utf-8. PHP-шаблоны, как и прочее в системе - в utf-8. При загрузке PHP-шаблонов, данные скармливаемые им, предварительно перекодируются из internal в utf-8. Перехваченный вывод потом перекодируется из utf-8 в internal. Плюсы - система может пользоваться стандартными PHP-функциями без оверхеда. Минусы - при обращении из шаблона к другим данным, не поданным непосредственно, в шаблоне нужно перекодирование (скажем, $title я могу перекодировать, а вот $items[0]->title() будет уже в системной кодировке). Придётся использовать функции преобразования из системной кодировки в utf-8. Т.е. если основные данные сможем выводить как есть:
Привет, <?=$title?>,
то внутренние данные уже придётся выводить в чём-то типа
Купите <?dc($items->title())?>,
где dc() занимается преобразованием intrnal -> utf-8. И это тоже некоторый оверхед, особенно, если, опять же, в цикле.
Был в голове ещё какой-то вариант, сейчас вылетел, но он совсем уж безумный :)
Пока я склоняюсь больше ко второму. Всё же, юникод юникодом, но в системе лучше жить в системной кодировке. Позволяет система включить utf8 - отлично. Нет - не нам выбирать... Кроме того, при реализации второго варианта нужно будет переписывать самый минимум готового кода.
Может быть свежий взгляд со стороны подскажет более изящное решение?
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от kto_tama
Ответ на:
комментарий
от true_admin
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от true_admin
Ответ на:
комментарий
от KRoN73
Ответ на:
комментарий
от grinn
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум Попытка подправить VIM (2003)
- Форум [Стол]Мозговой штурм (2011)
- Форум Задействовать Nexus 4 - мозговой штурм (2017)
- Форум Мозговой штурм на просторах родины (2005)
- Форум [Мозговой штурм] Переход на линукс (2007)
- Форум [без флейма][пишем СУБД]Требуется мозговой штурм (2010)
- Форум Мозговой штурм: темы для агитации за Linux (2007)
- Форум Мозговой штурм. Нифига не работает виртуализация для проброса. (2013)
- Форум компонентные фреймфорки? (2011)
- Форум Не знаю чем забивать 500-гигабайтный диск (мозговой штурм) (2013)