Уважаемые участники форума, помогите, пожалуста, разрешить проблему!
Использую сжатие вывода gzip и кодировку UTF-8.
В конце выводимого содержимого вижу кракозыбры! :(
Пример html-разметки:
</body></i3��d cl="r
в конце кракозябрики вместо закрывающего </html>
Вот заголовки, которые я получаю от своего скрипта:
PHP |
Date: Thu, 04 Jun 2009 11:26:37 GMT Server: Apache/2.2.4 (Win32) mod_ssl/2.2.4 OpenSSL/0.9.8d PHP/5.2.4 X-Powered-By: PHP/5.2.4 Content-Encoding: gzip Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 Expires: Thu, 01 Jan 1970 00:00:01 GMT Pragma: no-cache Last-Modified: Thu, 04 Jun 2009 11:26:37 GMT Content-Length: 994 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=UTF-< |
Алгоритм работы скрипта:
- буферизация вывода
- захват буфера
- сжатие буфера
- отправка заголовков
- отправка сжатого буфера
Проблема наблюдается, только когда в html присутствуют русские символы!
Думаю, что проблема с вычислением длины отдаваемого содержимого:
с резирвирования 2 байтов вместо 1 под символы русского алфавита и вследствие этого, кракозябры в конце,
т.к. длина не соотвествует отдаваемому количеству информации.
Вроде везде использую безопасные multi byte (mb_*) функции,
в регулярках везде использую ключ "u" (работаем с utf).
Проблемный участок, где происходит сжатие.
При отключённом сжатии, всё ОК.
PHP |
header_set('Content-Encoding', $encoding); // $encoding = 'UTF-8' echo "\x1f\x8b\x08\x00\x00\x00\x00\x00";
$page_size = mb_strlen($page_buffer); // $page_buffer - захваченный буфер $crc32 = crc32($page_buffer); $page_buffer = gzcompress($page_buffer, $compress_level); $page_buffer = mb_substr($page_buffer, 0, mb_strlen($page_buffer)-4);
return ($page_buffer.pack('V', $crc32).pack('V', $page_size)); |
Где бага, не могу понять!
Что нужно исправить?
Спустя 58 минут, 52 секунды (4.06.2009 - 15:48) FatCat написал(а):
В этом форуме используется gzip-компрессия, и при этом никаких проблем с кодировками.
Вот как это реализовано:
Заголовки не сжимаются; я и не представляю, как это может быть реализовано, просто файл index.php начинается со строк:
PHP |
<?php header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); |
Содержимое страницы собирается в переменную $ibforums->skin['template'] (почему именно такое имя - вопрос к разработчикам IPB).
Когда страница вся собрана,
PHP |
if ($ibforums->vars['disable_gzip'] != 1) { $buffer = ob_get_contents(); ob_end_clean(); ob_start('ob_gzhandler'); print $buffer; } print $ibforums->skin['template']; exit; |