Что DOMDocument делает с моей строкой?

$dom = new DOMDocument('1.0', 'UTF-8');

$str = '<p>Hello®</p>';

var_dump(mb_detect_encoding($str)); 

$dom->loadHTML($str);

var_dump($dom->saveHTML()); 

Просмотр.

Выходы

string(5) "UTF-8"

string(158) "<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body><p>Hello&Acirc;&reg;</p></body></html>
"

Почему мой Unicode ® был преобразован в &Acirc;&reg; и как мне остановить это?

Я сегодня схожу с ума?


person alex    schedule 21.02.2011    source источник


Ответы (3)


Ваш текстовый редактор говорит "®" в UTF-8, но байты в файле говорят "®" в латинице-1 (или похожей кодировке), которую PHP использует для чтения. Использование ссылки на объект персонажа устранит эту двусмысленность.

>>> print u'®'.encode('utf-8').decode('latin-1')
®
person Ignacio Vazquez-Abrams    schedule 21.02.2011
comment
Спасибо, что просветили меня (+1), но каким должен быть мой следующий шаг? Я снова чувствую себя новичком :P - person alex; 21.02.2011
comment
Мой следующий шаг — записать его как &reg; в коде; не стоит бороться с PHP из-за подобных вещей, так как нет больших шансов фактически выиграть битву повсюду. - person Ignacio Vazquez-Abrams; 21.02.2011

Вы можете добавить тег кодировки xml (и удалить его позже). Это работает для меня на вещах, которых нет в Centos 5.x (ubuntu, cpanel php):

<?php
$dom = new DOMDocument('1.0', 'UTF-8');
$str = '<p>Hello®</p>';
var_dump(mb_detect_encoding($str)); 
$dom->loadHTML('<?xml encoding="utf-8">'.$str);
var_dump($dom->saveHTML()); 

Это то, что ты получаешь:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<?xml encoding="utf-8"><html><body><p>Hello&reg;</p></body></html>

За исключением дней, когда вы получаете это:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<?xml encoding="utf-8"><html><body><p>Hello&Acirc;&reg;</p></body></html>
person Jan    schedule 23.04.2012

Я исправил это декодирование UTF-8, прежде чем передать его в loadHTML.

$dom->loadHTML( utf8_decode( $html ) );

saveHTML(), кажется, декодирует специальные символы, такие как немецкие умляуты, в их объекты HTML. (Хотя я поставил $dom->substituteEntities=false;... о.О)

Однако это довольно странно, поскольку в документации говорится:

Расширение DOM использует кодировку UTF-8.

(http://www.php.net/manual/de/class.domdocument.php, ищите utf8)

О боже, кодирование в PHP снова и снова создает проблемы... бесконечная история.

person graup    schedule 11.06.2012