Возврат предварительно сжатого статического содержимого вместо архивирования на лету - PullRequest
3 голосов
/ 02 марта 2012

У меня много статического текстового содержимого JSON, проиндексированного в базе данных. Часть этого контента больше 20К. Веб-страницы запрашивают это содержимое с помощью Ajax и вызова PHP-файла для извлечения данных из базы данных.

Конечно, можно сжать возвращенный контент на лету, но мне было интересно, смогу ли я получить предварительно сжатый контент и вернуть его напрямую из PHP. Другими словами, я мог предварительно записать записи и сохранить их в самой базе данных, а не в полном тексте.

Возможно ли это? Если да, как я могу указать в PHP, что возвращаемый контент является бинарным gzip-файлом? Я использую echo для простого текста, но какую команду использовать для двоичных данных? Я не эксперт по PHP. Спасибо.

Ответы [ 4 ]

2 голосов
/ 02 марта 2012

Альтернативный веб-сервер Apache

Во-первых, если вы используете Веб-сервер Apache , возможно, вы захотите включить и настроить mod_deflate .Он будет обрабатывать сжатие содержимого перед отправкой его клиенту.

Альтернатива PHP # 1

Если нет, то вы можете использовать ob_gzhandler (PHP 4> = 4.0.4, PHP 5) для активации буфера вывода gzip.

if(!ob_start("ob_gzhandler")) ob_start();
echo $json;

Альтернатива PHP # 2

Другая возможность (не тестировалась)может кэшировать содержимое на диске, а не помещать содержимое gzip в базу данных, если они чаще используются в несжатом формате.Использование gzencode .

$json = array('id' => $id, 'content' => $content);
$file = '/tmp/' . $json['id'] . '.json';
if(!file_exists($file)) {
  $gzip = gzencode($json['content']);
  file_put_contents($file, $gzip);
} else {
  $gzip = file_get_contents($file);
}
header('Content-Encoding: gzip');
header('Content-Length: '.strlen($gzip));
echo $gzip;

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

Альтернатива PHP #2.5

Вывод сжатого содержимого из кэша диска, когда браузер принимает его только.

$json = array('id' => $id, 'content' => $content);
if( strpos($_SERVER["HTTP_ACCEPT_ENCODING"],'gzip') !== false ) {
  $file = '/tmp/' . $json['id'] . '.json';
  if(!file_exists($file)) {
    $gzip = gzencode($json['content']);
    file_put_contents($file, $gzip);
  } else {
    $gzip = file_get_contents($file);
  }
  header('Content-Encoding: gzip');
  header('Content-Length: '.strlen($gzip));
  echo $gzip;
} else {
  echo $json['content'];
}
2 голосов
/ 02 марта 2012

Вы также должны повторить сжатые данные.echo - это просто «запись этих байтов в выходной буфер».Вы можете отображать изображения, если хотите.Интересно то, что вы говорите браузеру делать с данными.Именно здесь приходят заголовки ответа HTTP. Вам необходимо отправить заголовок Content-Encoding.Но вам нужно убедиться, что клиент в состоянии понять gzip, чтобы это работало вообще.Вы также должны знать, что используются два разных алгоритма сжатия: DEFLATE и GZIP.

<?php
$data = fetchGzippedDataFromDatabase();
if (stripos($_SERVER["HTTP_ACCEPT_ENCODING"], 'gzip') !== false) {
  header('Content-Encoding: gzip');
  header('Content-Length: ' . strlen($data));
  echo $data;
} else {
  // client does not accept gzipped data
  echo gzdecode($data);
  // or gzinflate() or gzuncompress() 
  // depending on what you used to compress in the first place
}

Возможно, вы захотите использовать обратный прокси-сервер (nginx, varnish, squid, ...) и обработать ихсжатие на выходе.

2 голосов
/ 02 марта 2012

Поскольку содержимое является статическим, я предлагаю вам полностью обойти шаг "fetch from db" и попробовать механизм кэширования, который поддерживает gzip-кодирование ответа или кэширование версии gzipped.

Здесьссылка на кого-то, кто сделал это для Apache.Другим решением будет Лак .

2 голосов
/ 02 марта 2012

Да, это возможно.

Вам потребуется изменить заголовки HTTP (Content-type, Content-Length, Transfer-Encoding) через функцию header .

Но будьте осторожны, вам необходимо проанализировать принятые кодировки передачи, предложенные клиентом (deflate, gzip и т. Д.), И обработать все из них. Если вы отправите deflate клиенту gzip или наоборот, он не будет работать должным образом.

Кроме того, помните, что существует разница между кодировкой передачи gzip и форматом файла gzip. Вам, вероятно, нужно найти библиотеку, которая реализует это в php, или выполнить грязную работу самостоятельно.

В любом случае, удачи!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...