loadHTML и кодировка

3м Буду!

Новичок
loadHTML и кодировка

Привет.
До создания поста рыл инет дня 3-4 как минимум. гугль поделился всем тем что проиндексировал, в том числе и две подобные темы на этом форуме. Однако, поскольку большенство решений сводились скорее к хакам к каждому конкретному случаю (формату и кодировке используемой в примере html-ины), мне всё-таки восжелалось нарыть некий более-менее универсальный способ, свободный от проблем с кодировками, и посколько конечного консенсуса, я так и не увидел, то скорее "АПну тему" чем создам дубль ;)

В общем, в процессе множественных тестов, выработал следующий, далеко не оптимальный алгоритм

1. загружаем входящий источник данных (ХТМЛ-страницу) в строковую переменную
2. проверяем наличие <meta ... charset=XXX>
2.1 если charset=utf-8, переходим к пункту 3
2.2 если charset != utf-8, делаем
PHP:
$utf_html = iconv($charset_encoding, 'UTF-8', $html)
2.2.1 нагло меняем <meta ... charset=XXX> на <meta ... charset=utf-8> в $utf_html
2.3 charset вообще нет - ну пытаемся угадать реальную кодировку различными методами (здесь, не суть важно)
3. @loadHTML($utf_html);

и так, сий способ глюкав до безобразия, но более-менее "уНиВерсаЛЬный", из замеченных глюкавостей, могу отметить следующие:
1. если конвертить из какой-либо кодировки в utf-8 (то есть исходный документ не в найтивной для libxml кодировке utf-8), то приходится юзать всяческие хаки, типа html_entity_decode (третий параметр которой подбирается опытным путём в каждом конкретном случае) и прочие
2. до saveXML (то есть, до выгрузки свалидированного дерева), при работе с текстовыми нодами (DOMNode::textContent), кириллица вообще находится непонятно в какой кодировке...
3. ну просто масса всего было замечено, особо актуальны эти два, если тема получит развитие - приведу здесь свои скрины, тесты и т.д.

оффтоп: Кроме того, как мне кажется, loadHTML не только учитывает значение <meta ... charset=XXX>, но ещё и пытается "угадать" реально используемую кодировку.

Собственно, резюмируя вопросами, перечислю наиболее актуальные для меня:

1. как всё-таки достаточно безгеморно и "универсально" (на сколько это возможно) работать с различными кодировками при использовании DOMDocument::loadHTML

2. DOMDocument::loadHTML всё конвертит в UTF-8 из... ???
2.1 если есть <meta ... charset=XXX>
2.2 если его не указали

3. как заставить DOMDocument::loadHTML НЕ производить АВТОМАТИЧЕСКОЕ преобразования при загрузке документа (php.ini, ещё что-то и т.д. не дожидаясь PHP6)

Вот как бы всё на том уровне, на котором я представляю себе "глубь и ширь" сабжевой траблы.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
что такое loadHTML ?

-~{}~ 23.03.09 19:05:

и чего ты вообще хочешь, собственно?
 

3м Буду!

Новичок
и чего ты вообще хочешь, собственно?
отсыпите? ;)

зы: с проблемой разобрался, быть может кому будет полезно:
в общем все траблы с кодировкой при использовании DOMDocument::loadHTML(), могут возникать в тех случаях, если до тега <meta ... charset=XXX> (где ХХХ - имя кодировки) встречается любой символ, отличный от латиницы.

То есть, достаточно что-то вроди
PHP:
$new_html = preg_replace('(<head.*?)(.+?)(<meta.+?charset.+?>)', '${1}${3}${2}', $html, 1);
(разумеется, это просто например).

Как оказалось, DOMDocument::loadHTML() врубает некую "эвристику" и для определения кодировки использует не только значение <meta ... charset=XXX>, но и ещё какие-то другие параметры.

зы: не знаю, описано ли это где-либо кроме как в исходниках самой библиотеки, но вот то что в официальном мануале ПХП об этом ни слова - это факт. В общем, пожалуйста исправляйте если где оказался не прав )

-~{}~ 24.03.09 11:05:

кстати, ещё один ИМХО полезный факт, не описаный в мануале и относящийся к сабжу - DOMDocument::saveXML() выполняет обратное преобразование внутреннего представления в DOM в кодировке UTF-8, в оригинальную, то есть в ту, которая указана в <meta ... charset=XXX> или в ту, которую посчитает за используемую (и как в 99% случаев неправильно), если встретит хоть один не латинский символ до явного указания кодировки.
 
Сверху