Рабочий процесс UTF8 PHP, MySQL обобщен

Я работаю для международных клиентов, у которых все очень разные алфавиты, и поэтому я пытаюсь, наконец, получить обзор полного рабочего процесса между PHP и MySQL, который обеспечил бы правильное вложение всех кодировок символов. Я прочитал кучу учебников по этому вопросу, но у меня есть вопросы (есть чему поучиться), и я подумал, что могу просто собрать все это вместе и спросить.

PHP

header('Content-Type:text/html; charset=UTF-8'); mb_internal_encoding('UTF-8'); 

HTML

 <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <form accept-charset="UTF-8"> .. </form> 

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

MySQL

CREATE database_name DEFAULT CHARACTER SET utf8; или ALTER database_name DEFAULT CHARACTER SET utf8; и / или использовать utf8_general_ci качестве сопоставления соединений MySQL.

(здесь важно отметить, что это увеличит размер базы данных, если использует varchar)

соединение

 mysql_query("SET NAMES 'utf8'"); mysql_query("SET CHARACTER_SET utf8"); 

Бизнес-логика

обнаруживать, если не UTF8 с mb_detect_encoding() и конвертировать с ivon() .
проверка слишком длинных последовательностей UTF8 и UTF16

 $body=preg_replace('/[\x00-\x08\x10\x0B\x0C\x0E-\x19\x7F]|(?<=^|[\x00-\x7F])[\x80-\xBF]+|([\xC0\xC1]|[\xF0-\xFF])[\x80-\xBF]*|[\xC2-\xDF]((?![\x80-\xBF])|[\x80-\xBF]{2,})|[\xE0-\xEF](([\x80-\xBF](?![\x80-\xBF]))|(?![\x80-\xBF]{2})|[\x80-\xBF]{3,})/',' ',$body); $body=preg_replace('/\xE0[\x80-\x9F][\x80-\xBF]|\xED[\xA0-\xBF][\x80-\xBF]/S','?', $body); 

Вопросов

  • это mb_internal_encoding('UTF-8') необходимый в PHP 5.3 и выше, и если это так, я должен использовать все многобайтные функции вместо своих основных функций, таких как mb_substr() вместо substr() ?

  • все еще необходимо проверить наличие уродливых входных укусов, и если да, то для чего это надежная функция / класс? Я, возможно, не хочу снимать плохие данные и не знаю достаточно о транслитерации.

  • должно ли это быть utf8_general_ci или, скорее, utf8_bin ?

  • есть ли что-то в вышеупомянутом рабочем процессе?

источники:

 http://coding.smashingmagazine.com/2012/06/06/all-about-unicode-utf8-character-sets/ http://webcollab.sourceforge.net/unicode.html http://stackoverflow.com/a/3742879/1043231 http://www.adayinthelifeof.nl/2010/12/04/about-using-utf-8-fields-in-mysql/ http://akrabat.com/php/utf8-php-and-mysql/ 

    • mb_internal_encoding('UTF-8') ничего не делает сам по себе, он устанавливает только параметр кодировки по умолчанию для каждой функции mb_ . Если вы не используете какую- mb_ функцию mb_ , это не имеет никакого значения. Если это так, имеет смысл установить его, поэтому вам не нужно передавать параметр $encoding каждый раз отдельно.
    • IMO mb_detect_encoding в основном бесполезен, поскольку принципиально невозможно точно определить кодировку неизвестного текста. Вы должны знать, какая кодировка содержит текст, потому что у вас есть спецификация об этом, или вам нужно проанализировать соответствующие метаданные, например заголовки или метатеги, где указан кодировка.
    • Использование mb_check_encoding для проверки правильности текста mb_check_encoding в кодировке, которую вы ожидаете, в ней, как правило, достаточно. Если это не так, отбросьте его и введите соответствующую ошибку.
    • Что касается:

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

      Если вы манипулируете строками, содержащими многобайтовые символы, то да, вам нужно использовать функции mb_ чтобы избежать ошибочных результатов. Основные функции строки работают только на уровне байтов, а не на уровне символов, что обычно требуется при работе со строками.

    • utf8_general_ci vs. utf8_bin делает только разницу при сортировке , т.е. сортировке и сравнении строк. С utf8_bin данные обрабатываются в двоичной форме, т.е. идентичны только идентичные данные. С utf8_general_ci некоторая логика, например, «é» сортируется вместе с «e», а верхний регистр считается равным нижнему регистру.

    должно ли это быть utf8_general_ci или, скорее, utf8_bin?

    Вы должны использовать utf8_bin для поиска по регистру , иначе utf8_general_ci

    это mb_internal_encoding ('UTF-8'), необходимый в PHP 5.3 и выше, и если это так, я должен использовать все многобайтные функции вместо своих основных функций, таких как mb_substr () вместо substr ()?

    Да, конечно, если у вас многобайтовая строка, вам нужно работать с семейной функцией mb_ *, за исключением бинарной безопасной php стандартной функции, такой как str_replace (); (и несколько других)

    все еще необходимо проверить наличие уродливых входных укусов, и если да, то для чего это надежная функция / класс? Я, возможно, не хочу снимать плохие данные и не знаю достаточно о транслитерации.

    Хм, нет, вы не можете это проверить.