Кодировки, локали .... ?

Slam

Новичок
Кодировки, локали .... ?

Здравствуйте ув. коллеги!

У меня есть некая мозаика, которую хотелось бы сложить в единую картинку!

Вот в чем собственно ситуация.
Есть сайт который будет "говорить" минимум на 4 языках. Причем языки довольно своелбразные: финский, шведский, английский, немецкий, украинский, русский. И это для начала.

Соответственно посетители будут разнообразные и данные они будут вписывать тоже на разных языках. Естественно и клиентские кодировки будут различные.

Тут и появляется ряд вопросов.

1) По скольку в проекте (на PHP5) для хранения данных используется СУБД MySQL 4+/5, то в какой кодировке лучшее их держать. Полагаю, что UTF-8.

2) Если UTF-8, то какая библиотека лучше iconv или встроенная в PHP mbstring?

3) Существует ли способы и методы автоматического определения пользовательских кодировок?

4) какие тонкости следует учесть при работе с setlocale?

Возможно у Вас есть какие-то концепции для применения в подобніх ситуациях?

Буду рад любой помощи!

Заранее благодарен!
 

tf

крылья рулят
3) <meta http-equiv="content-type" content="text/html; charset=windows-1251">
4) http://phpclub.ru/talk/search.php?s=&action=showresults&searchid=1348990&sortby=after&sortorder=descending
 

Gorynych

Посетитель PHP-Клуба
Vital_N данные зашитые в коде вряд ли будут в UTF-8, даже если все, что вводится через административный интерфейс приедет в Юникоде.

Slam

как ни смешно, но лично я перестал пытаться удержать все в одной кодировке. Хотя на выводе ориентируюсь именно на Юникод, и там где это возможно - использу. его в качестве кодировки БД

для перекодировки на лету использую mbstring, но она склонна ошибаться при автоопределении кодировки текста. Даже при выставлении корректно русской локали и переопределения порядка кодировок (это к вопросу 3)

русская локаль для 1251 -
PHP:
setlocale(LC_ALL, array ('ru_RU.CP1251', 'rus_RUS.1251'));
и это важно

хочу напомнить, что кроме данных в БД и поступивших из веб-формы бывают и строки в коде. И они не в Юникоде. Т.е. непллохо иметь представление о том, что потоки данных могут быть в разных кодировках, и должны преобразовываться. Кстати - опять хочется отослать к докладу Змиевского на PHPConf :)

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

Vital_N

Новичок
Автор оригинала: Gorynych
Vital_N данные зашитые в коде вряд ли будут в UTF-8, даже если все, что вводится через административный интерфейс приедет в Юникоде.
почему бы не перегнать весь проект в юникод?
 

Gorynych

Посетитель PHP-Клуба
tf
верю. Но консирвативен и под Виндой люблю старый добрый EditPlus, а как в таком случае быстро подправить скрипт в терминальном окне на FreeBSD - вообще не представляю.

P.S. иногда у меня просто нет другой возможности, кроме как работать через XTerm или SSH-клиент
 

tf

крылья рулят
Gorynych, иногда лучше перейти на что-то новое чем так себя мучить ;)
 

Gorynych

Посетитель PHP-Клуба
tf
ну не знаю. Во-первых я себя так не мучаю. Во-вторых, это упрощает переносимость и совместное использование кода.
 

tf

крылья рулят
Gorynych, код приведи вывода данных зашитых в коде
 

Slam

Новичок
ОК! Это я все вразумил!
Как привильно определить в какой кодировке данные пришли от юзера и как лучше хранить в базе!

А строки из файлов зная в какой они кодировке я так понимаю не проблема переконвертить :)
 

Gorynych

Посетитель PHP-Клуба
класс приводить не буду, приведу частично метод, ответсвенный именно за вывод данных, записанных в скрипте (и, находящихся в кодировке скрипта) в выходной поток (в кодировке выходного потока :). Там изначально несколько перестраховок из серии "если нет этой функции - попробуем другую", но общий принцип думаю будет ясен:
PHP:
        public static function scriptOutput($txt) {
            static $method = null;
            static $locale = null;

            if ( !isset($locale) && self::$locale ) {
                $locale = true;
                setlocale(LC_ALL, self::$locale);
            }
            if ( !isset($method) && function_exists("mb_convert_encoding") ) {
                $method = "mb_convert_encoding";
            }

            ....~~... 

            return $method($txt, self::$output_encoding, self::$script_encoding);
        }
сам вывод тут не причем, тут все танцы вокруг преобразования одной кодировки в другую

-~{}~ 05.10.06 19:04:

Как привильно определить в какой кодировке данные пришли от юзера и как лучше хранить в базе!
мы в праве ожидать, что данные от пользователя приходят в той же кодировке, которую мы используем для вывода (указываем в charset).

как вариант - в случае ошибки можно еще анализировать $_SERVER['HTTP_ACCEPT_CHARSET'], но предлагаю пока в эти дебри не забираться
 

Gorynych

Посетитель PHP-Клуба
tf
код активный, но все что относится к преобразованию из кодировки скрипта в кодировку выходного при условии, что включена поддержка mbstring я привел, что-то еще хочется?

статические переменные используются для однократных вычислений (при повторном вызове метода уже определены),

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

ну вот еще примерчик, если непонятна применимость. Это уже внешняя "просто функция" (ну есть такие малкие полезные функции, которые бессмысленно куда-либо инкапсулировать а под рукой они полезны периодически):
PHP:
function println($var=null, $encoding=true) {
        if ( $encoding ) {
            echo UniText::scriptOutput($var)."<br />\n";
        } else {
            echo "$var<br />\n";
        }
}
по умолчанию, println(string) "дернет" для преобразования уже описанный метод scriptOutput из класса UniText, но при желании можем заблокировать перекодирование.
 

Gorynych

Посетитель PHP-Клуба
tf
я проблем как-то не вижу. Скорее я сейчас намеренно подстраиваю некоторые вещи под схему, которую озвучивал Андрей Змиевский, говоря о перспективах PHP 6 ( http://www.gravitonic.com/talks/ )

~~

может стоит еще добавить, что метод scriptOutput не единственный, у него есть близкие родственники, в том числе ответственные за преобразования ИЗ/В кодировку файловой системы. Знаете, данные иногда надо брать отдавать из/в совершенно разые места, не только из/в браузер/БД
 

Slam

Новичок
Так, что-то я уже и запутался! Давайте сложим логическую цепочку! Итак, Ваши предложения:

Получаем данные / Преобразовуем / Сохраняем / Выводим

Какие особенности на данных этапах? Может есть еще какие-то?
 

tf

крылья рулят
если тебе нужно несколько языков на сайте то луше используй unicode
 

Slam

Новичок
tf

Каким именно образом ? Везде?
Я вот и спрашиваю про лог цепочку.
 
Сверху