Вывод вашего приложения должен содержать только одну выходную кодировку. Если у вас есть несколько чанков, которые кодируются по-разному, то браузер получит результат, с которым невозможно работать. Отсюда ошибка кодирования.
Сама Кохана уже использует выходной буфер. Если вы хотите объединить это с выходным буфером ob_gzhandler, вам нужно запустить буфер до того, как kohana инициализирует его. Это связано с тем, что выходной буфер является наращиваемым. Когда kohana закончит буферизацию вывода, вы примените:
ob_start('ob_gzhandler'); # your buffer:
ob_starts and ends by kohana
Таким образом, всякий раз, когда kohana выполнила какой-либо вывод, эти куски будут переданы в ваш обратный вызов вывода (ob_gzhandler()
) и будут закодированы в gz.
В этом случае браузер должен получать только данные в кодировке gz, поскольку это был выходной буфер на самом верхнем уровне.
Использование ob_gzhandler и ручное отображение буфера
Если вы используете ob_start('ob_gzhandler')
, чтобы позволить PHP справиться со сжатием, а затем вы echo ob_get_clean()
, вы создадите ненадежный вывод. Это связано с тем, как работает компрессия с выходной буферизацией:
PHP будет буферизовать порции вывода. Это означает, что PHP начинает сжимать вывод, но оставляет несколько байтов для продолжения сжатия. Таким образом, ob_get_clean () возвращает пока что сжатую часть буфера. Часто этот результат не является полным.
Чтобы справиться с этим, сначала очистите буфер:
ob_start('ob_gzhandler') OR ob_start();
echo 'eh?';
ob_flush();
$gz = ob_get_clean();
echo $gz;
И убедитесь, что у вас больше нет выхода после этого.
Если бы PHP достиг конца вашего скрипта, он бы позаботился об этом: очистка и вывод.
Теперь вам нужно вручную вызвать ob_flush()
, чтобы явно заставить PHP проталкивать буфер через обратные вызовы.
Проверка проблем сжатия HTTP с помощью Curl
Поскольку firefox будет возвращать ошибку, необходим другой инструмент для проверки причины кодирования. Вы можете использовать curl
для отслеживания происходящего:
curl --compress -i URL
Запрашивает URL с включенным сжатием при отображении всех заголовков ответов и тела без кодировки. Это необходимо, поскольку PHP прозрачно включает / отключает сжатие обратного вызова ob_gzhandler
на основе заголовков запросов.
Ответ также показывает, что PHP также установит необходимые заголовки ответа. Поэтому нет необходимости указывать их вручную. Это было бы даже опасно, потому что только вызывая ob_start('ob_gzhandler')
, вы не можете сказать, включено сжатие или нет.
Если сжатие нарушено, curl
выдаст описание ошибки, но не отобразит тело.
Ниже приведено такое сообщение об ошибке скручивания, которое вызвано не полностью сгенерированным выводом неисправного php-скрипта:
HTTP/1.1 200 OK
X-Powered-By: PHP/5.3.6
Content-Encoding: gzip
...
curl: (23) Error while processing content unencoding: invalid code lengths set
Добавив переключатель --raw
, вы можете даже достичь пика в необработанном теле ответа:
curl --compress --raw -i URL
Это может создать впечатление, что происходит не так, как несжатые части тела.