Исправление сломанной кодировки UTF8 - PullRequest
58 голосов
/ 28 августа 2009

Я пытаюсь исправить неправильную кодировку UTF8. Я в настоящее время использую PHP 5 и MySQL

В моей базе данных есть несколько случаев плохих кодировок, которые печатаются как: î

  • Сортировка базы данных: utf8_general_ci
  • PHP использует правильный заголовок UTF8
  • Notepad ++ настроен на использование UTF8 без спецификации
  • управление базой данных обрабатывается в phpMyAdmin
  • не все случаи символов с акцентом разбиты

Мне нужна какая-то функция, которая поможет мне сопоставить экземпляры îÂ, ƒÂ, àи других подобных им с их правильными символами UTF8 с акцентом.

Ответы [ 12 ]

92 голосов
/ 16 декабря 2010

Если у вас есть двойные символы 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/

78 голосов
/ 19 августа 2010

Если вы 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

Скачать:

https://github.com/neitanod/forceutf8

62 голосов
/ 28 августа 2009

В прошлом мне приходилось пытаться «исправить» ряд неработающих ситуаций с UTF8, и, к сожалению, это никогда не бывает легким, а зачастую довольно невозможным.

Если вы не можете точно определить, как он был сломан, и он всегда был сломан таким же образом, тогда будет трудно "отменить" ущерб.

Если вы хотите попытаться устранить ущерб, лучше всего начать с написания некоторого примера кода, в котором вы пытаетесь выполнить множество вариантов вызовов mb_convert_encoding (), чтобы посмотреть, сможете ли вы найти комбинацию «из» и « к 'это исправляет ваши данные. В конце концов, часто лучше даже не беспокоиться об исправлении старых данных из-за сопутствующих уровней боли, а просто исправить ситуацию в будущем.

Однако, прежде чем сделать это, вы должны убедиться, что вы в первую очередь исправили все, что вызывает эту проблему. Вы уже упоминали, что параметры сортировки и базы данных вашей БД установлены правильно. Но есть и другие места, где вам нужно проверить, чтобы убедиться, что все в порядке UTF-8:

  • Убедитесь, что вы используете свой HTML как UTF-8:
    • header ("Content-Type: text / html; charset = utf-8");
  • Измените кодировку PHP по умолчанию на utf-8:
    • ini_set ("default_charset", 'utf-8');
  • Если ваша база данных ВСЕГДА не общается в utf-8, то вам может потребоваться указать это для каждого соединения, чтобы убедиться, что она работает в режиме utf-8, в MySQL вы делаете это, выпуская:
    • charset utf8
  • Вам может потребоваться указать вашему веб-серверу, чтобы он всегда пытался общаться в UTF8, в Apache эта команда:
    • AddDefaultCharset UTF-8
  • Наконец, вам ВСЕГДА нужно убедиться, что вы используете функции PHP, которые соответствуют требованиям UTF-8. Это означает, что вы всегда должны использовать строковые функции в стиле mb _ *. Это также означает, что при вызове функций, таких как htmlspecialchars (), в конце необходимо включить соответствующий параметр кодировки 'utf-8', чтобы убедиться, что он не кодирует их неправильно.

Если вы пропустите какой-либо один шаг через весь ваш процесс, кодирование может быть искажено, и могут возникнуть проблемы. Как только вы попадаете в «канавку» выполнения utf-8, все это становится второй натурой. И, конечно же, PHP6, как предполагается, является полностью юникодной жалобой от getgo, что облегчит многое (надеюсь)

11 голосов
/ 14 июля 2014

У меня была проблема с xml-файлом, который имел неправильную кодировку, он сказал, что это utf-8, но в нем были символы, которые не были utf-8.
После нескольких проб и ошибок с mb_convert_encoding() мне удается исправить с помощью

mb_convert_encoding($text, 'Windows-1252', 'UTF-8')
10 голосов
/ 04 марта 2010

Как указал Дэн: вам нужно преобразовать их в двоичный файл, а затем преобразовать / исправить кодировку.

Например, для utf8, сохраненного как latin1, следующий SQL исправит это:

UPDATE table
   SET field = CONVERT( CAST(field AS BINARY) USING utf8)
 WHERE $broken_field_condition
2 голосов
/ 24 ноября 2009

Способ состоит в том, чтобы преобразовать в двоичный файл и затем исправить кодировку

2 голосов
/ 29 августа 2009

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

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;
}

Кажется, это отлично работает для удаления двойной кодировки, которую я испытываю. Я, вероятно, скучаю по некоторым персонажам, которые могут быть проблемой для других. Тем не менее, для моих нужд это работает отлично.

1 голос
/ 08 марта 2015

Еще одна вещь, которую нужно проверить, которая оказалась моим решением (найдено здесь ), - это как данные возвращаются с вашего сервера. В моем приложении я использую 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'"));
0 голосов
/ 16 ноября 2016

У этого скрипта был хороший подход. Преобразование его на язык по вашему выбору не должно быть слишком сложным:

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;
}
0 голосов
/ 26 февраля 2013

Я нашел решение после нескольких дней поиска. Мой комментарий будет похоронен, но в любом случае ...

  1. Я получаю поврежденные данные с php.

  2. Я не использую имена набора UTF8

  3. Я использую utf8_decode () в моих данных

  4. Я обновляю свою базу данных новыми декодированными данными, все еще не используя имена набора UTF8

и вуаля:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...