Какой метод сжатия использовать в PHP? - PullRequest
60 голосов
/ 07 марта 2009

У меня есть большой объем данных для перемещения с использованием двух сценариев PHP: один на стороне клиента, использующий сценарий PHP из командной строки, а другой за Apache. Я размещаю данные на стороне сервера и использую поток ввода php: // для их сохранения на стороне веб-сервера. Чтобы не допустить достижения каких-либо ограничений памяти, данные разделяются на порции по 500 КБ для каждого запроса POST. Все это прекрасно работает.

Теперь, чтобы сохранить пропускную способность и ускорить ее, я хочу сжать данные перед отправкой и распаковать при получении на другом конце. Я нашел 3 пары функций, которые могут выполнять эту работу, но я не могу решить, какую из них использовать:

Какую пару функций вы бы порекомендовали и почему?

ОБНОВЛЕНИЕ: Я только что прочитал zlib FAQ:

Формат gzip (gzencode) был разработан для хранения справочной информации об одном файле, такой как имя и дата последнего изменения. Формат zlib (gzcompress), с другой стороны, был разработан для приложений в оперативной памяти и каналах связи, имеет гораздо более компактный заголовок и трейлер и использует более быструю проверку целостности, чем gzip.

Ответы [ 4 ]

79 голосов
/ 07 марта 2009

Все это можно использовать. Есть тонкие различия между тремя:

  • gzencode () использует формат файла GZIP, такой же, как инструмент командной строки gzip. Этот формат файла имеет заголовок, содержащий необязательные метаданные, сжатые данные DEFLATE и нижний колонтитул, содержащий контрольную сумму CRC32 и проверку длины.
  • gzcompress () использует формат ZLIB. Он имеет более короткий заголовок, служащий только для идентификации формата сжатия, сжатых данных DEFLATE, и нижний колонтитул, содержащий контрольную сумму ADLER32.
  • gzdeflate () использует алгоритм DEFLATE самостоятельно, который является основой для обоих других форматов.

Все три используют один и тот же алгоритм под капотом. gzencode() добавляет возможность включать исходное имя файла и другие данные об окружающей среде (это не используется при простом сжатии строки). gzencode() и gzcompress() оба добавляют контрольную сумму, поэтому можно проверить целостность архива, что может быть полезно при ненадежных методах передачи и хранения. Если все хранится локально и вам не нужны никакие дополнительные метаданные, тогда достаточно gzdeflate(). Для переносимости я бы порекомендовал gzencode() (формат GZIP), который, вероятно, лучше поддерживается, чем gzcompress() (формат ZLIB) среди других инструментов.

При сжатии очень коротких строк накладные расходы каждого метода становятся релевантными, поскольку при очень коротких входных данных накладные расходы могут составлять значительную часть выходных данных. Издержки для каждого метода, измеряемые путем сжатия пустой строки, составляют:

  • gzencode('') = 20 байтов
  • gzcompress('') = 8 байтов
  • gzdeflate('') = 2 байта
43 голосов
/ 07 марта 2009

Я не эксперт по PHP и не могу ответить на поставленный вопрос, но, похоже, здесь много догадок и нечеткой информации.

DEFLATE - это имя алгоритма сжатия, который используется ZLIB, GZIP и другими. Теоретически, GZIP поддерживает альтернативные алгоритмы сжатия, но на практике их нет.

Нет такой вещи, как "алгоритм GZIP". GZIP использует алгоритм DEFLATE и размещает данные кадрирования вокруг сжатых данных. С помощью GZIP вы можете добавлять такие вещи, как имя файла, время файла, CRC, даже комментарий. Эти метаданные не являются обязательными, и многие gzippers просто опускают их.

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

Это все в RFC IETF 1950 , 1951 и 1952 .

Сказать, что «алгоритм gzip сжимает лучше, чем DEFLATE» - это просто глупость. Там нет алгоритма gzip. И алгоритм, используемый в формате GZIP , является DEFLATE .

6 голосов
/ 07 марта 2009

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

0 голосов
/ 09 марта 2019

Мне пришлось распаковать сжатый GZIP-файл в PHP с C ++. Я обнаружил, что PHP gzencode и его аналог gzdecode используют метод Z_NO_FLUSH и в конце блока данных для кодирования / декодирования применяют Z_FINISH. Пример / учебник на языке C, показанный на веб-сайте zlib, можно использовать для распаковки и сжатия сжатых файлов из PHP, если бит Windows и уровень памяти изменяются, чтобы разрешить дефляции и инфляции в gzip.

Дополнительно: кажется, что большинство людей в этой теме понятия не имеют, что означает "метод сжатия".

...