Данные MySQL не отображаются в кодировке символов, в которой они должны быть - PullRequest
0 голосов
/ 20 сентября 2011

Во-первых, спасибо всем, кто читает это.У меня очень странная проблема с кодировкой символов в базе данных MySQL, с которой я использую PDO PHP для взаимодействия.Все таблицы закодированы с использованием UTF8, веб-приложение использует utf-8, но кажется, что данные, хранящиеся в базе данных, на самом деле не utf-8, а latin-1.

В течение некоторого времени все работало нормальновремя, но это вызывает проблемы при импорте файлов данных в кодировке utf-8 или выполнении полнотекстового поиска, который содержит специальные символы, такие как «é» или «ë».

EDIT :

В некоторых ответах высказано предположение, что это проблема моего терминала.Это не:

foreach($dbh->query("SELECT c FROM t") as $row){
    echo $row['c'] ."\n";
    echo urlencode($row['c'])."\n";
}
$dbh->exec("SET NAMES 'latin1'");
foreach($dbh->query("SELECT c FROM t") as $row){
    echo $row['c'] ."\n";
    echo urlencode($row['c'])."\n";
}
$dbh->exec("SET NAMES 'utf8'");
foreach($dbh->query("SELECT c FROM t") as $row){
    echo $row['c'] ."\n";
    echo urlencode($row['c'])."\n";
}

Выводит следующее:

é
%C3%A9f
é
%C3%A9f
é
%C3%83%C2%A9f

Спасибо всем до сих пор.

КОНЕЦ РЕДАКТИРОВАНИЯ

Итак, сначала я проверяю, что таблицы работают должным образом:

USE information_schema;

mysql> SELECT table_collation FROM tables WHERE table_schema="mydb" and table_name="mytable";
+-----------------+
| table_collation |
+-----------------+
| utf8_general_ci |
+-----------------+
1 row in set (0.00 sec)

mysql> SELECT character_set_name,collation_name FROM information_schema.columns WHERE table_schema="mydb" and table_name="t" and column_name="c";
+--------------------+-----------------+
| character_set_name | collation_name  |
+--------------------+-----------------+
| utf8               | utf8_general_ci |
+--------------------+-----------------+
1 row in set (0.00 sec)

Однако данные выглядят не как utf-8, а как latin-1:

mysql> use mydb;
Database changed

mysql> SET NAMES 'latin1';
Query OK, 0 rows affected (0.00 sec)

mysql> select c from t;
+---+
| c |
+---+
| é |
+---+
1 row in set (0.00 sec)

mysql> SET NAMES 'utf8';
Query OK, 0 rows affected (0.00 sec)

mysql> select c from t;
+----+
| c  |
+----+
| é |
+----+
1 row in set (0.00 sec)

Итак, у меня два вопроса:

1) Самое главное, что я могу сделать с данными, уже находящимися в БД?

2) Есть ли способ настроить БД так, чтобыон на самом деле использует utf-8 при подключении или мне нужно каждый раз выполнять запрос SET NAMES?

Большое спасибо за ваше время и помощь,

Мэтт

Ответы [ 4 ]

1 голос
/ 20 сентября 2011

это ваш терминал оказался в латинице 1, а не в данных:)

Есть ли способ настроить БД так, чтобы она действительно использовала utf-8

вы уже настроили его.
единственное, что вам нужно, это настроить клиентскую кодировку, которая выполняется SET NAMES 'utf8'

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

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

что я могу сделать с данными, уже находящимися в БД?

все, что вы пожелаете, пока ваш БД не возвращает ? отметок.
чтобы восстановить ваши данные, вы должны установить имена для кодировки данных, заданной для таблицы. это предотвратит перекодировку данных в mysql. Таким образом, вы можете получить или сбросить его, а затем загрузить его снова с правильными настройками.

EDIT

после некоторого рассмотрения я собираюсь сказать, что ваши данные находятся в utf8, в то время как кодировка таблицы как-то установлена ​​на latin1.

% C3% A9 - это совершенно правильное представление utf-8 символа é. (не знаю, где вы получили трейлинг f хотя)

, в то время как% C3% 83% C2% A9 - это кодированная в UTF-версии версия% C3% A9. Итак, кажется, ваша база данных думает, что ваши данные находятся в латинице 1 и кодируют их в utf8.

так что, когда вы устанавливаете имена на latin1, это не возражает и не перекодирует.

Вывод:

  1. дважды проверьте кодировку вашей таблицы (и полей). это должен быть латиница 1

  2. да, чтобы сохранить ваши данные, вы должны сделать что-то вроде

*** Боже, я ненавижу эту проблему автоформатирования, которая не позволяет мне публиковать код сразу после элемента списка

mysqldump --default_charset=latin1 mydb > mydb.sql

Затем проверьте этот дамп и измените каждый вид latin1 на utf8.
затем загрузите его обратно.

не забудьте сначала сделать резервную копию ваших данных!

0 голосов
/ 20 сентября 2011
  1. Подключение к вашей базе данных

  2. Установить подключение к UTF-8

    SET NAMES 'utf8';

В ваших файлах HTML:

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
0 голосов
/ 20 сентября 2011

использование

SET character_set_client = "UTF-8";

при соединении с вашим клиентом. в PHP вы достигнете этого с помощью функции:

set_charset($encoding)

до того, как вы выполните какие-либо фактические вставки / обновление данных

0 голосов
/ 20 сентября 2011

Если вы получили данные со страницы HTML и сохранили их в своей БД, не забудьте установить правильную кодировку текста в разделе head HTML :

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>

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

Относительно 1): Посмотрите на PHP

string utf8_decode ( string $data )

функцию, описанную здесь .Получить записи из вашей БД, перекодировать в нужную кодировку и записать обратно.

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