Я хотел бы убедиться, что все, что я знаю о UTF-8, правильно. Я уже некоторое время пытаюсь использовать UTF-8, но продолжаю сталкиваться со все большим количеством ошибок и других странных вещей, из-за которых кажется почти невозможным иметь сайт с 100% UTF-8. Где-то всегда есть что-то, чего мне не хватает. Возможно, кто-то здесь может исправить мой список или ОК, чтобы я не пропустил ничего важного.
База данных
Каждый сайт должен где-то хранить данные. Независимо от ваших настроек PHP, вы также должны сконфигурировать БД. Если вы не можете получить доступ к файлам конфигурации, убедитесь, что « SET NAMES 'utf8' », как только вы подключитесь. Кроме того, обязательно используйте utf8_ unicode_ ci на всех ваших столах. Это предполагает MySQL для базы данных, вам придется изменить для других.
Regex
Я делаю ОЧЕНЬ много регулярных выражений, которые на более сложны , чем ваш обычный поиск-замена. Я должен не забыть использовать модификатор "/ u", чтобы PCRE не повредил мои строки . Тем не менее, даже тогда существуют проблемы, по-видимому, .
Строковые функции
Все строковые функции по умолчанию (strlen (), strpos () и т. Д.) Следует заменить на Многобайтовые строковые функции , которые смотрят символ вместо байта.
Заголовки
Вы должны убедиться, что ваш сервер возвращает правильный заголовок, чтобы браузер знал, какую кодировку вы пытаетесь использовать (точно так же, как вы должны указать MySQL).
header ('Content-Type: text / html;
кодировка = UTF-8' ); * +1038 *
Также стоит добавить правильный тег в заголовок страницы. Хотя фактический заголовок переопределит это, если они будут отличаться.
<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 строки в памяти по-разному, в зависимости от того, какую кодировку он использует (например, типы файлов), или он все еще хранится как обычный фрагмент, причем некоторые символы интерпретируются по-разному (например, & amp; vs & in HTML). chazomaticus отвечает на этот вопрос:
В PHP (до PHP5, в любом случае), строки
это просто последовательности байтов. Есть
нет подразумеваемого или явного набора символов
связан с ними; это что-то
программист должен отслеживать.
Если передать функцию не-UTF-8 функции mb_ *, это когда-нибудь вызовет проблему?
Если строка UTF неправильно закодирована, что-то пойдет не так (например, ошибка синтаксического анализа в регулярном выражении?) Или просто пометит сущность как плохую (html)? Есть ли вероятность, что неправильно закодированные строки приведут к тому, что функция вернет FALSE, потому что строка плохая?
Я слышал, что вы должны также пометить ваши формы как UTF-8 (accept-charset = "UTF-8"), но я не уверен, в чем выгода ..?
Был ли UTF-16 записан для ограничения в UTF-8? Как в UTF-8 не хватило места для персонажей? (У2 (UTF) к?)
Функция
Вот пара пользовательских функций PHP, которые я нашел, но у меня нет никакого способа проверить, действительно ли они работают. Возможно, у кого-то есть пример, который я могу использовать. Сначала это convertToUTF8 () , а затем кажется_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;
}
Если кому-то интересно, я нашел отличный пример страницы для использования при тестировании UTf-8 .