Xpoint
   [напомнить пароль]

Сжатие с помощью ob_start('ob_gzhandler')

2006-02-17 11:59:10 [обр] Alexey St [досье]

Конф: FreeBSD, PHP 4.4.1
Применил следующий кусок кода, чтобы получить сжатие страниц, соответственно меньший траффик.

if (extension_loaded('zlib')) {
    ob_start('ob_gzhandler');
}

В конце страницы соотв. ob_end_flush();

Однако, замеры траффика показали нулевой результат. В чем могут быть грабли?

спустя 10 минут [обр] Lynn [досье]
В том, что браузер не посылает нужный заголовок.
Before ob_gzhandler() actually sends compressed data, it determines what type of content encoding the browser will accept ("gzip", "deflate" or none at all) and will return its output accordingly.
спустя 28 минут [обр] Alexey St [досье]
Lynn «Кофеман»[досье]
А разве ob_start('ob_gzhandler') не шлёт этот самый заголовок?
спустя 8 минут [обр] Alexey St [досье]

Lynn «Кофеман»[досье]
Извиняюсь за первый глупый вопрос :)))

Задаю второй, тоже наверное глупый:
А почему броузер не шлёт этот заголовок? Вроде бы все современные броузеры поддерживают сжатие.

спустя 19 минут [обр] Lynn [досье]
Думаете я телепат догадываться, какой у вас браузер?
Так же возможно, что этот заголовок режется каким-нибудь прокси-сервером по дороге.
спустя 2 минуты [обр] Alexey St [досье]
Win: XP SP2 Бровзер: IE 6.0
спустя 16 минут [обр] Victor Gr. [досье]

IE не шлёт (не слал по крайней мере)
до тех пор, пока у него в настройках не включишь HTTP/1.1 замест HTTP/1.0.

Протестируйте Firefox-ом, он точно работает.

Я написал свою функцию сжатия вместо ob_gzhandler:

function compression ($output) {

    if (isset ($_SERVER['HTTP_ACCEPT_ENCODING'])) {
        $HTTP_ACCEPT_ENCODING = $_SERVER['HTTP_ACCEPT_ENCODING'];
    }

    if (isset ($HTTP_ACCEPT_ENCODING)) {

        if (strpos ($HTTP_ACCEPT_ENCODING, 'gzip') !== False) {

            header ('Content-Encoding: gzip');
            $compressed_data    = gzencode ($output, GZIP_LEVEL);
            $compression_method = 'gzip';

        } elseif (strpos ($HTTP_ACCEPT_ENCODING, 'deflate') !== False) {

            header ('Content-Encoding: deflate');
            $compressed_data    = gzdeflate ($output, GZIP_LEVEL);
            $compression_method = 'deflate';

        } elseif (empty ($HTTP_ACCEPT_ENCODING)) {

            $compressed_data    = $output;
            $compression_method = 'no_compression';

        } elseif (!empty ($HTTP_ACCEPT_ENCODING)) {

            header ('HTTP/1.1 406 Not Acceptable');
            $compressed_data    = $output;
            $compression_method = 'not_allowed';
        }

    } else {

        $compressed_data    = $output;
        $compression_method = 'not_allowed';

    }

    $GLOBALS['compressed_size']    = strlen ($compressed_data);
    $GLOBALS['uncompressed_size']  = strlen ($output);
    $GLOBALS['compression_method'] = $compression_method;
    
    header ('Content-Length: ' . $GLOBALS['compressed_size']);
    return $compressed_data;
    
}

В начале страницы вместо ob_start ("ob_gzhandler"); пишем

ob_start ("compression");

в конце -

ob_flush ();

Т.о. в

    $GLOBALS['compressed_size']    = strlen ($compressed_data);
    $GLOBALS['uncompressed_size']  = strlen ($output);
    $GLOBALS['compression_method'] = $compression_method;

Храняться значения сжатого размера, несжатого, и метод компрессии, что можно спокойно записать в лог, чтобы потом смотреть коэффициенты сжатия и прочее, интересное.

Собственно, хотелось бы услышать критику этой функции, чтобы оптимизировать её и исправить ошибки.

Зачем я её писал? Чтобы узнать размер сжатой страницы.

спустя 16 минут [обр] Alexey St [досье]
Вообщем заработало сжатие в IE, но почему раньше не работало, так и не понял. Чудеса, одним словом.
спустя 2 часа 26 минут [обр] TroT [досье]
но почему раньше не работало

необходимые для сжатия заголовки от браузера мог резать фаервол или прокси

писать ob_end_flush(); ob_flush(); вконце не обязательно

Зачем я её писал? Чтобы узнать размер сжатой страницы.

узнать размер сжатой страницы можно обработчиком указаным раньше ob_start('ob_gzhandler');

ob_start('ob_saveAfter');
ob_start('ob_gzhandler');
ob_start('ob_saveBefore');
спустя 2 дня 18 часов [обр] Alexey St [досье]

Балин, вот обнаружилась такая ошибка.

Warning: ob_start(): output handler 'ob_gzhandler' cannot be used after 'URL-Rewriter' in z:\home\aaaaa.ru\www\kadr\index.php on line 5

Как это можно вылечить?

спустя 2 часа 13 минут [обр] TroT [досье]
при каких обстоятельставах появляется?
спустя 16 минут [обр] Alexey St [досье]
Ошибка возникает, если входишь сначала на адрес http://example.com/, появляется список директорий, выбираю директорию с сайтом, и ошибка возникает. Если идти прямой ссылкой на сайт http://example.com/kadr/, ошибок не возникает.
В принципе не критично, но все таки что это может быть?
спустя 3 часа [обр] TroT [досье]
а если http://example.com/kadr ?
спустя 1 час 24 минуты [обр] Alexey St [досье]
Извиняюсь, всех запутал. Ошибка всегда вылазит.
А проблема решилась путем перестановки строк. Раньше первой строчкой шел session_start();
2 if (extension_loaded('zlib')) {
3   ob_start('ob_gzhandler');
4 }
5
6 session_start();
Powered by POEM™ Engine Copyright © 2002-2005