Я работаю для международных клиентов, у которых все очень разные алфавиты, и поэтому я пытаюсь, наконец, получить обзор полного рабочего процесса между 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
каждый раз отдельно. 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 (); (и несколько других)
все еще необходимо проверить наличие уродливых входных укусов, и если да, то для чего это надежная функция / класс? Я, возможно, не хочу снимать плохие данные и не знаю достаточно о транслитерации.
Хм, нет, вы не можете это проверить.