DOMDocument windows-1251 -> utf8

Discussion in 'PHP' started by banned, 26 May 2011.

  1. banned

    banned Banned

    Joined:
    20 Nov 2006
    Messages:
    3,324
    Likes Received:
    1,193
    Reputations:
    252
    Беру страницу из инета в windows-1251.
    Делаю ей iconv (windows-1251, 'utf-8', $str);
    Пытаюсь засунуть контент в DomDocument, но он выдает херню... На выходе надо получить utf-8 кодировку.. Как тольо не пробовал.. Помогайте.
    Для примера страницы в windows-1251 возьмите любую страницу на ачате... например: http://forum.antichat.ru/threadnav40896-467-40.html
    PHP:
    <?php
        $str 
    parse($url);
        
    //$str = mb_convert_encoding($str, 'html-entities', 'utf-8');
        
        
       // var_dump($str);
        
        
    libxml_use_internal_errors(true);

        
    $doc = new DOMDocument('1.0''utf-8');
        
    $dom->preserveWhiteSpace false


        
    //$doc->recover = true;
        //libxml_clear_errors();

        //$str = utf8_decode($str);
        
    $doc->loadHTML($str);
        
    $dom->encoding 'utf-8'
        print 
    $doc->encoding."<br>\n";
        print 
    $doc->actualEncoding."<br>\n"
        
        
    var_dump($doc->saveHTML());
     
  2. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    В пхп вы получаете два костыля по цене одного.

    1) loadhtml просматривает заголовки meta и выдирает кодировку оттуда
    2) Даже выдрав кодировку он делает что то невообразимое и дважды перекодирует данные, или мне кажется? Без второго костыля получается iso-8859-1 в кодировке utf8

    PHP:
    <?PHP

    $str 
    file_get_contents('http://forum.antichat.ru/threadnav40896-467-40.html'); 

    // Костыль раз
    $str str_replace('windows-1251''utf-8'$str);
    $str iconv('windows-1251''utf-8'$str);
        
    libxml_use_internal_errors(true);

    $doc = new DOMDocument('1.0''utf-8');


    // Костыль 2
    $doc->loadHTML('<?xml encoding="UTF-8">' $str);

    $dom->encoding 'utf-8'
    print 
    $doc->encoding."<br>\n";
    print 
    $doc->actualEncoding."<br>\n"
        
    var_dump($doc->saveHTML());
     
    _________________________
    1 person likes this.
  3. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    Наверное, существует особая разновидность карго-культа в отношении кодировок.
    Code:
    <?php
    
    $str = file_get_contents('http://forum.antichat.ru/thread276036.html');
    
    libxml_use_internal_errors(true);
    
    $doc = new DOMDocument('1.0');
    $doc->loadHTML($str);
    
    print iconv($doc->encoding, 'utf-8', $doc->saveHTML());
    
     
  4. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    astrologer рекомендую внимательно посмотреть исходный выведенной страницы. И сделать побайтное сравнение вашего скрипта при
    PHP:
    print $doc->saveHTML();
    // И
    print iconv($doc->encoding'utf-8'$doc->saveHTML());
    Потом возвращаетесь и рассказываете, что поняли
     
    _________________________
  5. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    Первый в кодировке документа (cp1251), второй в utf-8 (что и нужно было "...на выходе надо получить utf-8 кодировку..."), больше отличий нет, а что вас смущает? Только вывод у меня в терминал а не на страницу, ну да это не важно.

    Ваша очередь рассказывать, что поняли и почему у всех такие сложности с кодировками. Искренне надеюсь расширить свои или общие знания.
     
    1 person likes this.
  6. Gifts

    Gifts Green member

    Joined:
    25 Apr 2008
    Messages:
    2,494
    Likes Received:
    807
    Reputations:
    614
    astrologer мм, да, пожалуй мне стоит все же обновить пхп. В версии 5.2.9 ваш скрипт возвращает:
    Собственно мой пост пытался указать на это поведение скрипта. В последних версиях этой проблемы действительно нет.

    Все же попытаюсь включить режим зануды - да, с запрошенным ваш код справляется правильно (на выходе получить utf-8 кодировку). Однако согласуясь с вашим способом решения этой задачи - работа DOMDocument превратится в ад, т.к. каждый возвращенный результат придется пропускать через iconv() - что является несколько печальным результатом работы. Или и тут я ошибаюсь?

    UPD. форум испортил энтайтлы
     
    _________________________
    #6 Gifts, 28 May 2011
    Last edited: 28 May 2011
  7. astrologer

    astrologer Elder - Старейшина

    Joined:
    30 Aug 2007
    Messages:
    837
    Likes Received:
    267
    Reputations:
    59
    Судя по всему нет, только при сериализации.

    Мой код тоже неправильный - надо по крайней мере учитывать заголовки http. Правильный алгоритм определения кодировки можно подсмотреть в спецификации html5.
     
  8. banned

    banned Banned

    Joined:
    20 Nov 2006
    Messages:
    3,324
    Likes Received:
    1,193
    Reputations:
    252
    После DomDocument я использую DomxPath и вот он как раз таки нормально выводит кодировку, не смотря на то что в домдокумент она ебанутая. Всем спасибо.