По некоторым причинам мои специальные символы были закодированы как следующая строка в базе данных mysql:
Ã?
Который проявляется как:
Ã?
Но на самом деле должно отображаться как:
Ö
Что здесь пошло не так? Я использую UTF-8 везде.
Как я могу это исправить, не воссоздавая весь контент?
Я выполнил следующее в PHP
:
<?php
echo str_replace("&", "&", htmlentities("Ö", 0, "ISO-8859-1")) , '<br />';
echo str_replace("&", "&", htmlentities("Ö", 0, "UTF-8")), "</br>";
?>
str_replace
просто чтобы раскрыть HTML
мнемоника, которая в противном случае
быть переведенным браузером на оригинальный персонаж, что я не хочу, чтобы это произошло.
Вы получите это как вывод:
�
Ö
Вы узнаете первое значение как то, что вы нашли в базе данных, а второе
немного так, как вы хотели, чтобы это было.
Добавьте к этому тот факт, что значение по умолчанию для третьего аргумента htmlentities
зависит от вашего PHP
версия и является 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("&", "&", 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, 'Ã�', 'Ö') where instr(myfield, 'Ã�') > 0;
update mytable set myfield = replace(myfield, 'õ', 'õ') where instr(myfield, 'õ') > 0;
update mytable set myfield = replace(myfield, 'Ũ', 'Ũ') where instr(myfield, 'Ũ') > 0;
update mytable set myfield = replace(myfield, 'Å©', 'ũ') where instr(myfield, 'Å©') > 0;
Конечно, вы можете решить сделать PHP
Сценарий, который будет даже делать обновления самостоятельно.
Надеюсь, вы можете использовать эту информацию для решения проблем.
Для PDO используйте что-то вроде
$db = new PDO('dblib:host=host;dbname=db;charset=UTF-8', $user, $pwd);
Ã?
две или три вещи идут не так, а не одна!
C396
является гексом utf8 для Ö
или латинский гекс для двух символов Ö
, Требуется что-то еще, чтобы пойти не так, чтобы получить ?
или черный бриллиант.
Давайте посмотрим, что в таблице; делать
SELECT col, HEX(col) FROM tbl WHERE ...
(Если вы уже сделали ранее предложенный replace()
Тогда стол может оказаться в еще худшем беспорядке. Или это может быть исправлено.)