У меня есть поле в MySQL типа text с использованием следующего сопоставления: utf8_general_ci
.
Это поле XML заполняется с помощью переменной, построенной с использованием DOMDocument:
function ed_audit_node($dom, $field, $new, $old){
//create audit_detail node
$ad = $dom->createElement('audit_detail');
$fn = $dom->createElement('fieldname');
$fn->appendChild($dom->createTextNode($field));
$ad->appendChild($fn);
$ov = $dom->createElement('old_value');
$ov->appendChild($dom->createTextNode($old));
$ad->appendChild($ov);
$nv = $dom->createElement('new_value');
$nv->appendChild($dom->createTextNode($new));
$ad->appendChild($nv);
//append to document
return $ad;
}
Воткак я сохраняю в БД ($ xml происходит от $ dom-> saveXML ()):
function ed_audit_insert($ed, $xml){
global $visitor;
$sql = <<<EOF
INSERT INTO ed.audit
(employee_id, audit_date, audit_action, audit_data, user_id)
VALUES (
{$ed[emp][employee_id]},
now(),
'{$ed[audit_action]}',
'{$xml}',
{$visitor[user_id]}
);
EOF;
$req = mysql_query($sql,$ed['db']) or die(db_query_error($sql,mysql_error(),__FUNCTION__));
//snip
}
Смотрите более старую, параллельную, слегка связанную тему о том, как я создаю этот XML: Другая ошибка синтаксического анализа PHP XML: «Неправильный ввод UTF-8, укажите кодировку!»
Что работает : - запрос к базе данных, выбор поля и его вывод с использованием jQuery(.ajax ()) и заполнение текстовой области.Firebug и textarea соответствуют содержимому базы данных (подтверждено с помощью Toad).
Что не работает : - вывод текста из базы данных на HTML-страницу.Эта HTML-страница имеет тип контента ISO-8859-1, который я не могу изменить.
Вот код, который выводит это на экран:
$xmlData = simplexml_load_string($d['audit_data']);
foreach ($xmlData->audit_detail as $a){
echo "<p> straight from db = ".$a->new_value."</p>";
echo "<p> utf8_decode() = ".utf8_decode($a->new_value)."</p>";
}
Я также использовалРасширение charset для Firefox: безуспешно пробовал ISO-8859-1, UTF-8 и 1252.
Если это был UTF-8, разве я не должен видеть алмазы с вопросительными знаками внутри (так как это контент?тип = ISO-8859-1)Если это не UTF-8, что это?
Edit # 1
Вот снимок других моих тестов:
<code>$xmlData = simplexml_load_string($d['audit_data']);
foreach ($xmlData->audit_detail as $a){
echo "<p>encoding is, straight from db, using mb_detect_encoding: ".mb_detect_encoding($a->new_value)."</p>";
echo "<p>encoding is, with utf8_decode, using mb_detect_encoding: ".mb_detect_encoding(utf8_decode($a->new_value))."</p>";
echo "<hr/>";
echo "<p> straight from db = <pre>".$a->new_value."
"; echo"
utf8_decode () =
".utf8_decode($a->new_value)."
"; echo""; $ iso88591_2 = iconv ('UTF-8', 'ISO-8859-1', $ a-> new_value); $ iso88591_3 = mb_convert_encoding ($ a-> new_value, 'ISO-8859-1', 'UTF-8 '); echo "
iconv () =". $ Iso88591_2. "
"; echo "
mb_convert_encoding () =". $ Iso88591_3. "
";}
Редактировать # 2
Я добавил фирменный тег FF, xmp.
Код:
<code>$xmlData = simplexml_load_string($d['audit_data']);
foreach ($xmlData->audit_detail as $a){
echo "<p>encoding is, straight from db, using mb_detect_encoding: ".mb_detect_encoding($a->new_value)."</p>";
echo "<p>encoding is, with utf8_decode, using mb_detect_encoding: ".mb_detect_encoding(utf8_decode($a->new_value))."</p>";
echo "<hr/>";
echo "<p> straight from db = <pre>".$a->new_value."
";echo "
utf8_decode () =
".utf8_decode($a->new_value)."
";эхо ""; $ iso88591_2 = iconv ('UTF-8', 'ISO-8859-1', $ a-> new_value); $ iso88591_3 = mb_convert_encoding ($ a-> new_value, 'ISO-8859-1', 'UTF-8 '); echo "
iconv () =". $ Iso88591_2. "
"; echo "
mb_convert_encoding () =". $ Iso88591_3. "
"; echo ""; echo"
прямо из базы данных, используя = ". $ a-> new_value."
"; echo"
utf8_decode (), используя = ". Utf8_decode ($ a-> new_value)."
";}
Вот некоторые метатеги со страницы:
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<meta name="dc.language" scheme="ISO639-2/T" content="eng" />
IMO, последний метатег не имеет отношения.
Редактировать # 3
Исходный код:
<code><p>encoding is, straight from db, using mb_detect_encoding: UTF-8</p><p>encoding is, with utf8_decode, using mb_detect_encoding: ASCII</p><hr/><p> straight from db = <pre>Ro马eç ³é ¥n franê¡©s
utf8_decode ()=
Ro?e??n fran?s
iconv () = Ro
mb_convert_encoding () = Ro? E ?? n fran? S
прямо из базы данных, используя = Roé © ¬eç ³é ¥ n franê¡ © s
utf8_decode (), используя = Ro? E?? n fran? s
Edit # 4
Вот оператор SQL, поступающий в базу данных:
INSERT INTO ed.audit
(employee_id, audit_date, audit_action, audit_data, user_id)
VALUES (
75,
now(),
'u',
'<?xml version="1.0"?>
<audit><audit_detail><fieldname>role_fra</fieldname><old_value>aRo马e砳頥n franꡩs</old_value><new_value>bRo马e砳頥n franꡩs</new_value></audit_detail></audit>
',
333
);
!Обратите внимание, что текст этого XML не обязательно соответствует приведенным выше снимкам экрана.
Edit # 5
Вот моя новая функция, которая оборачивает тег CDATA вокруг моих значенийдля узлов old_value и new_value:
function ed_audit_node($dom, $field, $new, $old){
//create audit_detail node
$ad = $dom->createElement('audit_detail');
$fn = $dom->createElement('fieldname');
$fn->appendChild($dom->createTextNode($field));
$ad->appendChild($fn);
$ov = $dom->createElement('old_value');
$ov->appendChild($dom->createCDATASection($old));
$ad->appendChild($ov);
$nv = $dom->createElement('new_value');
$nv->appendChild($dom->createCDATASection($new));
$ad->appendChild($nv);
//append to document
return $ad;
}
Я также добавил кодировку в документ XML:
$dom = new DomDocument('1.0', 'UTF-8');
Вот мой новый вызов simpleXML:
$xmlData = simplexml_load_string($d['audit_data'], "SimpleXMLElement", LIBXML_NOENT | LIBXML_NOCDATA);
Я также вижу теги CDATA в Toad.Тем не менее, я все еще получаю сообщение об ошибке:
Warning: simplexml_load_string() [function.simplexml-load-string]: Entity: line 2: parser error : Input is not proper UTF-8, indicate encoding ! Bytes: 0xE9 0xE9 0x6C 0x65 in <snip>
Edit # 6
Я только что заметил, что вызов jQuery возвращает правильные акцентированные символы в CDATA.