2015-11-01 2 views
0

По какой-то причине мои специальные символы получили закодированной в виде следующей строки в базе данных MySQL:Revert плохо закодированные умляуты

Ã? 

проявляющимся как:

Ã? 

Но на самом деле должны отображаться как:

Ö 
  1. Что пошло сонате здесь? Я использую UTF-8 везде.

  2. Как исправить это, не воссоздавая весь контент?

+0

Вы используете PDO? Возможно, посмотрите на это:> PDO :: MYSQL_ATTR_INIT_COMMAND http://stackoverflow.com/questions/10209777/php-pdo-with-special-characters –

+0

, если плохая кодировка согласована, вы можете использовать php или MySQL для поиска и replace –

+0

@BartScheffer Я не использую PDO, но я установил '$ mysqlconn-> set_charset (" utf8 ");' – clamp

ответ

2

я выполнил следующее PHP:

<?php 
echo str_replace("&", "&amp;", htmlentities("Ö", 0, "ISO-8859-1")) , '<br />';  
echo str_replace("&", "&amp;", htmlentities("Ö", 0, "UTF-8")), "</br>"; 
?> 

str_replace только там, чтобы выявить какие-либо HTML мнемоники, которые бы в противном случае быть переведены в браузере на оригинальный характер, который я не» Я хочу, чтобы это случилось.

Вы получите это как выход:

&Atilde;� 
&Ouml; 

Вы узнаете первое значение, как то, что вы нашли в базе данных, а второй один немного, как вы хотели, чтобы это было. Добавьте к этому факт, что значение по умолчанию для третьего аргумента для htmlentities depends on your PHP version и является ISO-9959-1 в случае версии 5.3, той, которую вы используете. Также поймите, что HTML документов, которые не указывают кодировку символов, будут по умолчанию данные формы сообщения в формате ISO-8859-1. Объединяя все это может дать подсказку о причине вашей проблемы:

Моя догадка, что данные правильно размещены в UTF-8 на сервер, а затем htmlentities интерпретирует это как не- UTF-8, одного байта кодировки, и поэтому он превращает один, многобайтовый символ в два одиночных байтовых символа.

Теперь меры, чтобы принять, что это не по-прежнему случаются:

Сначала убедитесь, что ваш HTML форма имеет UTF-8 кодирование, потому что это определяет кодировку по умолчанию, что форма будет использоваться для передачи его данных на сервер:

<head> 
    <meta charset="UTF-8"> 
</head> 

убедитесь, что это не будет отменено другой кодировки в accept-charset атрибута форме тега.

Затем пропустите звонок htmlentities. Вы не должны превращать символы в их HTML mnemonic при их хранении в базе данных. MySql поддерживает UTF-8 символов, поэтому просто храните их вот так.

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

<?php 
    // list all your non-ASCII characters here. Do not use str_split. 
    $chars = ["Ö","õ","Ũ","ũ"]; 
    foreach ($chars as $ch) { 
     $bad = str_replace("&", "&amp;", htmlentities($ch, 0, "ISO-8859-1")); 
     echo "update mytable set myfield = replace(myfield, '$bad', '$ch') 
       where instr(myfield, '$bad') > 0;<br />"; 
    } 
?> 

Вывод этого сценария будет выглядеть следующим образом:

update mytable set myfield = replace(myfield, '&Atilde;�', 'Ö') where instr(myfield, '&Atilde;�') > 0; 
update mytable set myfield = replace(myfield, '&Atilde;&micro;', 'õ') where instr(myfield, '&Atilde;&micro;') > 0; 
update mytable set myfield = replace(myfield, '&Aring;&uml;', 'Ũ') where instr(myfield, '&Aring;&uml;') > 0; 
update mytable set myfield = replace(myfield, '&Aring;&copy;', 'ũ') where instr(myfield, '&Aring;&copy;') > 0; 

Конечно, вы можете решите создать сценарий PHP, который даже сделает сами обновления.

Надеюсь, вы сможете использовать эту информацию для устранения проблем.

+0

Спасибо за подробный ответ! первая часть верна! это было вызвано различными версиями php на dev-сервере и live-сервере. о второй части, мне, возможно, придется вернуться к вам завтра, так как сегодня я не могу проверить этот скрипт прямо сейчас. – clamp

0

Для PDO, использовать что-то вроде

$db = new PDO('dblib:host=host;dbname=db;charset=UTF-8', $user, $pwd); 

&Atilde;? это два или три вещи происходит не так, а не только один! C396 - это utf8 hex для Ö или латинский hex для двух символов Ö. Это требует чего-то другого, чтобы пойти не так, чтобы получить ? или черный бриллиант.

Посмотрим, что находится в таблице; сделать

SELECT col, HEX(col) FROM tbl WHERE ... 

(Если вы уже сделали ранее предложил replace(), то таблица может быть в еще худшем беспорядке. Или это может быть исправлено.)

Смежные вопросы