Я хотел бы убедиться, что все, что я знаю о UTF-8, является правильным. Я пытаюсь использовать UTF-8 некоторое время, но я продолжаю спотыкаться о все больше и больше ошибок и других странных вещей, из-за которых почти невозможно иметь 100% -ный сайт UTF-8. Где-то всегда есть что-то, что я, кажется, пропущу. Возможно, кто-то здесь может исправить мой список или ОК, поэтому я не пропущу ничего важного.Я правильно поддерживаю UTF-8 в своих PHP-приложениях?
Database
Каждый сайт должен хранить там данные где-то. Независимо от ваших настроек PHP вы также должны настроить БД. Если вы не можете получить доступ к файлам конфигурации, убедитесь, что «SET NAMES« utf8 »« как только вы подключаетесь. Кроме того, обязательно используйте utf8_ unicode_ ci на всех ваших таблицах. Это предполагает, что MySQL для базы данных, вам придется изменить для других.
Regex
Я делаю много регулярных выражений, которое more complex чем ваш средний поиск замены. Я должен помнить, чтобы использовать модификатор «/ u», чтобы PCRE doesn't corrupt my strings. Тем не менее, даже тогда есть still problems apparently.
Строковые функции
Все строки по умолчанию функций в (STRLEN(), StrPos() и т.д.) должны быть заменены на Multibyte String Functions, что смотреть на персонажа вместо байта.
Заголовки Вы должны убедиться, что ваш сервер возвращает правильный заголовок для браузера, чтобы знать, что набор символов вы пытаетесь использовать (так же, как вы должны сказать MySQL).
header ('Content-Type: text/html; charset = utf-8');
Также рекомендуется помещать правильный правильный тег < в заголовок страницы. Хотя фактический заголовок будет отменять это, если они будут отличаться.
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
Вопросы
Мне нужно, чтобы преобразовать все, что я получаю от пользовательского агента (HTML-форм в & URI) в UTF-8 Есть ли при загрузке страницы или если я могу просто оставить строки/как они есть и все еще управляют ими через эти функции без проблем?
Если мне нужно преобразовать все в UTF-8 - то какие шаги я должен предпринять? mb_detect_encoding, кажется, построен для этого, но я все вижу, что люди жалуются, что это не всегда работает. mb_check_encoding также кажется, что проблема связана с хорошей строкой UTF-8 из искаженной.
ли PHP хранить строки в памяти по-разному в зависимости от того, какой кодировки он использует (например, тип файлов), или он по-прежнему сохраняется, как обычные жала с некоторыми из символов интерпретируются по-разному (например, & усилителя, против & в HTML).
chazomaticus отвечает на этот вопрос:
В PHP (до PHP5, во всяком случае), строки являются только последовательности байтов. Существует не подразумеваемый или явный набор символов , связанный с ними; это что-то программист должен отслеживать.
Если a дает строку, отличную от UTF-8, функции mb_ *, это когда-нибудь вызовет проблему?
Если строка UTF некорректно закодирована, что-то пойдет не так (например, ошибка синтаксического анализа в регулярном выражении?) Или она просто пометит объект как плохой (html)? Есть ли вероятность, что неправильно закодированные строки приведут к возврату функции FALSE, потому что строка плохая?
Я слышал, что вы также должны указывать свои формы как UTF-8 (accept-charset = "UTF-8"), но я не уверен, в чем преимущество.?
Был ли UTF-16 написан для ограничения лимита в UTF-8? Как UTF-8 заканчивается для символов? (У2 (UTF) к?)
Функции
Вот пара пользовательских PHP функций, которые я нашел, но у меня нет никакого способа проверить, что они на самом деле работают. Возможно, у кого-то есть пример, который я могу использовать. Сначала это convertToUTF8(), а затем seem_utf8 из wordpress.
function seems_utf8($str) {
$length = strlen($str);
for ($i=0; $i < $length; $i++) {
$c = ord($str[$i]);
if ($c < 0x80) $n = 0; # 0bbbbbbb
elseif (($c & 0xE0) == 0xC0) $n=1; # 110bbbbb
elseif (($c & 0xF0) == 0xE0) $n=2; # 1110bbbb
elseif (($c & 0xF8) == 0xF0) $n=3; # 11110bbb
elseif (($c & 0xFC) == 0xF8) $n=4; # 111110bb
elseif (($c & 0xFE) == 0xFC) $n=5; # 1111110b
else return false; # Does not match any model
for ($j=0; $j<$n; $j++) { # n bytes matching 10bbbbbb follow ?
if ((++$i == $length) || ((ord($str[$i]) & 0xC0) != 0x80))
return false;
}
}
return true;
}
function is_utf8($str) {
$c=0; $b=0;
$bits=0;
$len=strlen($str);
for($i=0; $i<$len; $i++){
$c=ord($str[$i]);
if($c > 128){
if(($c >= 254)) return false;
elseif($c >= 252) $bits=6;
elseif($c >= 248) $bits=5;
elseif($c >= 240) $bits=4;
elseif($c >= 224) $bits=3;
elseif($c >= 192) $bits=2;
else return false;
if(($i+$bits) > $len) return false;
while($bits > 1){
$i++;
$b=ord($str[$i]);
if($b < 128 || $b > 191) return false;
$bits--;
}
}
}
return true;
}
Если кому-то интересно, я нашел большой пример страницы использовать when testing UTf-8.
На самом деле, у вас есть это в обратном порядке. UTF-8 был написан для решения проблем с UTF-16. В частности, UTF-16 требует, чтобы каждый символ занимал 2 байта (16 бит), а нам, американским программистам, это не понравилось, так как это означало бы, что все наши файлы удваиваются по размеру, поэтому они создали UTF-8, который был назад совместим с ASCII, и, таким образом, все файлы с чистым ASCII будут действительны в UTF-8, тем самым избавив многих людей от необходимости конвертировать все их файлы исходного кода из ASCII в UTF-16. –
Я не вижу упоминания о используемом mb_internal_encoding. Вы можете посмотреть на это и посмотреть, не имеет ли это никакого отношения к вам. –
Для MySQL не вызывайте вручную 'set names', потому что он не обновляет кодировку, используемую для real_escape_string. Вместо этого используйте 'mysql_set_character_set'. См. Http://dev.mysql.com/doc/refman/5.0/ru/mysql-set-character-set.html и http://stackoverflow.com/a/1317239/632951 – Pacerier