Я занимаюсь исправлением некорректной кодировки UTF8. В настоящее время я использую PHP 5 и MySQL
В моей базе данных у меня есть несколько примеров неправильных кодировок, которые печатаются так: î
Мне нужна какая-то функция, которая поможет мне сопоставить экземпляры î, ÃÂ, ü и других подобных им с их соответствующими акцентированными символами UTF8.
Я должен был попытаться «исправить» ряд обломанных ситуаций UTF8 в прошлом, и, к сожалению, это никогда не бывает легко, а зачастую и невозможно.
Если вы не можете точно определить, как он был сломан, и он всегда был сломан точно так же, тогда будет трудно «отменить» урон.
Если вы хотите попытаться отменить повреждение, лучше всего начать писать примерный код, где вы производите многочисленные варианты вызовов mb_convert_encoding (), чтобы увидеть, можете ли вы найти комбинацию «от» и «до», что исправляет ваши данные. В конце концов, часто лучше даже не беспокоиться о том, чтобы зафиксировать старые данные из-за связанных с этим уровней боли, но вместо этого просто исправить ситуацию в будущем.
Однако, прежде чем делать это, вам нужно убедиться, что вы исправите все, что вызывает эту проблему, в первую очередь. Вы уже упоминали, что сортировка и редакторы таблиц базы данных установлены правильно. Но есть еще места, где вам нужно проверить, чтобы все было правильно UTF-8:
Если вы пропустите какой-либо один шаг через весь процесс, кодировка может быть искажена и возникают проблемы. Как только вы попадаете в «паз» для выполнения utf-8, все это становится второй натурой. И, конечно же, PHP6 должен быть полностью разовой жалобой от getgo, что сделает многое из этого проще (надеюсь)
Если у вас есть двойные кодированные символы UTF8 (различные умные кавычки, тире, апостроф, котировка и т. Д.), В mysql вы можете сбросить данные, а затем прочитать их обратно, чтобы исправить сломанную кодировку.
Как это:
mysqldump -h DB_HOST -u DB_USER -p DB_PASSWORD --opt --quote-names \ --skip-set-charset --default-character-set=latin1 DB_NAME > DB_NAME-dump.sql mysql -h DB_HOST -u DB_USER -p DB_PASSWORD \ --default-character-set=utf8 DB_NAME < DB_NAME-dump.sql
Это было 100% исправление для моего двойного кодированного UTF-8.
Источник: http://blog.hno3.org/2010/04/22/fixing-double-encoded-utf-8-data-in-mysql/
Если вы utf8_encode()
в строке, которая уже является UTF-8, то она выглядит искаженной, когда она кодируется несколько раз.
Я сделал функцию toUTF8()
которая преобразует строки в UTF-8.
Вам не нужно указывать, что такое кодировка ваших строк. Это могут быть Latin1 (iso 8859-1), Windows-1252 или UTF8 или их сочетание.
Я сам использовал это в канале с смешанными кодировками в одной строке.
Применение:
$utf8_string = Encoding::toUTF8($mixed_string); $latin1_string = Encoding::toLatin1($mixed_string);
Моя другая функция fixUTF8()
исправляет искаженные строки UTF8, если они были закодированы в UTF8 несколько раз.
Применение:
$utf8_string = Encoding::fixUTF8($garbled_utf8_string);
Примеры:
echo Encoding::fixUTF8("Fédération Camerounaise de Football"); echo Encoding::fixUTF8("Fédération Camerounaise de Football"); echo Encoding::fixUTF8("FÃÂédÃÂération Camerounaise de Football"); echo Encoding::fixUTF8("Fédération Camerounaise de Football");
выведет:
Fédération Camerounaise de Football Fédération Camerounaise de Football Fédération Camerounaise de Football Fédération Camerounaise de Football
Скачать:
Как заметил Дэн, вам нужно преобразовать их в двоичные, а затем преобразовать / исправить кодировку.
Например, для utf8, хранящегося как latin1, следующий SQL исправит его:
UPDATE table SET field = CONVERT( CAST(field AS BINARY) USING utf8) WHERE $broken_field_condition
У меня была проблема с xml-файлом, который имел сломанную кодировку, он сказал, что это utf-8, но у него были символы, где не utf-8.
После нескольких проб и ошибок с mb_convert_encoding()
мне удалось исправить это с помощью
mb_convert_encoding($text, 'Windows-1252', 'UTF-8')
Я знаю, что это не очень элегантно, но после того, как было упомянуто, что строки могут быть закодированы двойным образом, я сделал эту функцию:
function fix_double encoding($string) { $utf8_chars = explode(' ', 'À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö'); $utf8_double_encoded = array(); foreach($utf8_chars as $utf8_char) { $utf8_double_encoded[] = utf8_encode(utf8_encode($utf8_char)); } $string = str_replace($utf8_double_encoded, $utf8_chars, $string); return $string; }
Кажется, это отлично работает, чтобы удалить двойное кодирование, которое я испытываю. Вероятно, мне не хватает некоторых персонажей, которые могут быть проблемой для других. Однако для моих нужд он работает отлично.
Способ преобразования в двоичный код, а затем для исправления кодировки
Еще одной проверкой, которая оказалась моим решением (найдено здесь ), является то, как данные возвращаются с вашего сервера. В моем приложении я использую PDO для подключения от PHP к MySQL. Мне нужно было добавить флаг к соединению, которое говорит, что данные вернутся в формате UTF-8
Ответ был
$dbHandle = new PDO("mysql:host=$dbHost;dbname=$dbName;charset=utf8", $dbUser, $dbPass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'"));
Похоже, что ваш utf-8 интерпретируется как iso8859-1 или Win-1250 в какой-то момент.
Когда вы говорите: «В моей базе данных у меня есть несколько примеров неправильных кодировок» – как вы это подтвердили? Через ваше приложение, phpmyadmin или клиент командной строки? Все ли коды utf-8 отображаются так или только некоторые? Возможно, у вас были неправильные кодировки, и он был неправильно преобразован из iso8859-1 в utf-8, когда он уже был utf-8?
у меня была такая же проблема давным-давно, и она исправила ее, используя
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">
Я нашел решение после нескольких дней поиска. Мой комментарий будет похоронен, но в любом случае …
Я получаю поврежденные данные с помощью php.
Я не использую имена наборов UTF8
Я использую utf8_decode () для своих данных
Я обновляю свою базу данных своими новыми декодированными данными, все еще не использую имена наборов UTF8
и вуаля 🙂
Этот сценарий имел хороший подход. Преобразование его на выбранный вами язык не должно быть слишком сложным:
http://plasmasturm.org/log/416/
#!/usr/bin/perl use strict; use warnings; use Encode qw( decode FB_QUIET ); binmode STDIN, ':bytes'; binmode STDOUT, ':encoding(UTF-8)'; my $out; while ( <> ) { $out = ''; while ( length ) { # consume input string up to the first UTF-8 decode error $out .= decode( "utf-8", $_, FB_QUIET ); # consume one character; all octets are valid Latin-1 $out .= decode( "iso-8859-1", substr( $_, 0, 1 ), FB_QUIET ) if length; } print $out; }