За последние 24 часа нас посетили 18650 программистов и 1600 роботов. Сейчас ищут 919 программистов ...

gzcompress+UTF-8+Кириллица или кракозябры в последних байтах

Тема в разделе "Прочие вопросы по PHP", создана пользователем scam87, 4 июн 2009.

  1. scam87

    scam87 Активный пользователь

    С нами с:
    4 июн 2009
    Сообщения:
    3
    Симпатии:
    0
    Уважаемые участники форума, помогите, пожалуста, разрешить проблему!

    Использую сжатие вывода gzip и кодировку UTF-8.
    В конце выводимого содержимого вижу кракозыбры! :(
    Пример html-разметки:
    </body></i3��d cl="r
    в конце кракозябрики вместо закрывающего </html>

    Вот заголовки, которые я получаю от своего скрипта:
    PHP:
    1. Date: Thu, 04 Jun 2009 11:26:37 GMT
    2. Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4
    3. X-Powered-By: PHP/5.2.4
    4. Content-Encoding: gzip
    5. Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    6. Expires: Thu, 01 Jan 1970 00:00:01 GMT
    7. Pragma: no-cache
    8. Last-Modified: Thu, 04 Jun 2009 11:26:37 GMT
    9. Content-Length: 994
    10. Keep-Alive: timeout=5, max=100
    11. Connection: Keep-Alive
    12. Content-Type: text/html; charset=UTF-8
    Алгоритм работы скрипта:
    - буферизация вывода
    - захват буфера
    - сжатие буфера
    - отправка заголовков
    - отправка сжатого буфера

    Проблема наблюдается, только когда в html присутствуют русские символы!
    Думаю, что проблема с вычислением длины отдаваемого содержимого:
    с резирвирования 2 байтов вместо 1 под символы русского алфавита и вследствие этого, кракозябры в конце,
    т.к. длина не соотвествует отдаваемому количеству информации.

    Вроде везде использую безопасные multi byte (mb_*) функции,
    в регулярках везде использую ключ "u" (работаем с utf).

    Проблемный участок, где происходит сжатие.
    При отключённом сжатии, всё ОК.

    PHP:
    1. header_set('Content-Encoding', $encoding); // $encoding = 'UTF-8'
    2. echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
    3.  
    4. $page_size = mb_strlen($page_buffer); // $page_buffer - захваченный буфер
    5. $crc32 = crc32($page_buffer);
    6.        
    7. $page_buffer = gzcompress($page_buffer, $compress_level);
    8.        
    9. $page_buffer = mb_substr($page_buffer, 0, mb_strlen($page_buffer)-4);
    10.  
    11. return ($page_buffer.pack('V', $crc32).pack('V', $page_size));
    Где бага, не могу понять!

    Что нужно исправить?
     
  2. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    А как насчет:

    PHP:
    1. <?
    2.  
    3. $gz_content = iconv("WINDOWS-1251", "UTF-8", ob_get_contents());
    4.  
    5. // И уже сжимать строку $gz_content
    6. // gzencode или gzcompress
    7.  
    8. ?>
     
  3. scam87

    scam87 Активный пользователь

    С нами с:
    4 июн 2009
    Сообщения:
    3
    Симпатии:
    0
    У меня:
    - шаблоны
    - значения из базы (сама база)
    в UTF-8
    поэтому мне не нужно делать дополнительных преоразований. правильно?
     
  4. Apple

    Apple Активный пользователь

    С нами с:
    13 янв 2007
    Сообщения:
    4.984
    Симпатии:
    2
    А сам файл скрипта сохранен в кодировке UTF-8 ?
    Преобразования не требуются только тогда, когда все операции с кодировкой выполняются согласованно: получили в ней, работаем с ней и отдаем именно в ней.

    А вы попробуйте мой вариант и тогда сделаете вывод, нужны дополнительные преобразования или нет.
    Если нужны, значит выясняем причину, по которой они нужны и устраняем.
     
  5. захват и сжатие я надеюсь, через ob_gzhandler или zlib.output_compression ?