Gzcompress: примеры (PHP)

Использование gzcompress в PHP для сжатия данных
Раздел: Сжатие
gzcompress(string $data, int $level = -1, int $encoding = ZLIB_ENCODING_DEFLATE): string|false
Описание функции gzcompress

Функция gzcompress используется для сжатия строки данных с использованием алгоритма ZLIB (RFC 1950). Этот метод сжатия часто применяется для уменьшения объема данных, передаваемых по сети или хранимых на диске, когда не требуется совместимость с форматом GZIP.

Когда используется

Функцию используют, когда необходимо сжать произвольные строковые данные (например, сериализованные объекты, JSON, HTML) для экономии пространства. Результат не включает заголовки файлов GZIP, что делает его более легковесным по сравнению с gzencode.

Аргументы функции
string gzcompress(string $data, int $level = -1, int $encoding = ZLIB_ENCODING_DEFLATE)

$data - строка данных для сжатия.

$level - уровень сжатия от -1 до 9. -1 - уровень по умолчанию ZLIB (обычно 6). 0 - без сжатия, 1 - минимальное сжатие (быстро), 9 - максимальное сжатие (медленно).

$encoding - одна из констант: ZLIB_ENCODING_RAW, ZLIB_ENCODING_DEFLATE или ZLIB_ENCODING_GZIP. По умолчанию используется ZLIB_ENCODING_DEFLATE.

Примеры использования
Базовое сжатие

Сжатие строки с уровнем по умолчанию.

$data = "Это тестовая строка для сжатия " . str_repeat("!", 100);
$compressed = gzcompress($data);
echo 'Исходный размер: ' . strlen($data) . ' байт<br>';
echo 'Сжатый размер: ' . strlen($compressed) . ' байт';
Исходный размер: 121 байт
Сжатый размер: 45 байт
Сжатие с разными уровнями

Сравнение размеров при разных уровнях сжатия.

$data = str_repeat("Hello World ", 100);
for ($level = 0; $level <= 9; $level++) {
    $compressed = gzcompress($data, $level);
    echo "Уровень $level: " . strlen($compressed) . " байт<br>";
}
Уровень 0: 1205 байт
Уровень 1: 48 байт
Уровень 2: 40 байт
Уровень 3: 38 байт
Уровень 4: 36 байт
Уровень 5: 35 байт
Уровень 6: 35 байт
Уровень 7: 35 байт
Уровень 8: 34 байт
Уровень 9: 34 байт
Использование разных методов кодирования
$data = "Тестовые данные";
$raw = gzcompress($data, -1, ZLIB_ENCODING_RAW);
$deflate = gzcompress($data, -1, ZLIB_ENCODING_DEFLATE);
$gzip = gzcompress($data, -1, ZLIB_ENCODING_GZIP);
echo 'RAW: ' . strlen($raw) . ' байт<br>';
echo 'DEFLATE: ' . strlen($deflate) . ' байт<br>';
echo 'GZIP: ' . strlen($gzip) . ' байт';
RAW: 29 байт
DEFLATE: 31 байт
GZIP: 41 байт
Похожие функции в PHP

Создает сжатую строку в формате GZIP (RFC 1952). Результат включает заголовок и контрольную сумму. Используют для создания файлов .gz или ответов HTTP с кодировкой gzip.

Сжимает строку с использованием алгоритма DEFLATE (RFC 1951), без заголовков ZLIB. Формат более "сырой", может быть полезен для специфичных протоколов.

gzinflate и gzuncompress

Функции для распаковки данных, сжатых gzdeflate и gzcompress соответственно. Важно использовать соответствующую пару сжатие/распаковка.

Когда что использовать

gzcompress подходит для внутреннего сжатия данных в программе. gzencode применяют для веб-ответов или создания GZIP файлов. gzdeflate нужен для низкоуровневой работы или совместимости с другими системами, использующими чистый DEFLATE.

Альтернативы в других языках

Gzcompress в Python

Модуль zlib предоставляет функции compress и decompress. Уровень сжатия задается от 0 до 9.

import zlib
data = b"Test data for compression" * 10
compressed = zlib.compress(data, level=6)
print(f"Original: {len(data)}, Compressed: {len(compressed)}")
Original: 230, Compressed: 36
JavaScript (Node.js)

Используют модуль zlib. Метод zlib.deflate соответствует gzcompress в PHP с кодированием DEFLATE.

const zlib = require('zlib');
const data = 'Test data'.repeat(10);
zlib.deflate(data, (err, buffer) => {
    console.log(`Original: ${data.length}, Compressed: ${buffer.length}`);
});
Original: 90, Compressed: 22

Gzcompress в MySQL

Функция COMPRESS сжимает строку с использованием алгоритма zlib и добавляет 4-байтовый префикс с длиной.

SELECT LENGTH(COMPRESS(REPEAT('MySQL data ', 100))) AS compressed_length;
compressed_length: 52
Отличия от PHP

В Python и JS по умолчанию используется уровень сжатия 6, как и в PHP. Формат данных на выходе может отличаться из-за заголовков. MySQL COMPRESS добавляет префикс, которого нет в результате gzcompress.

Типичные ошибки
Некорректный уровень сжатия

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

$compressed = gzcompress("data", 12);
Warning: gzcompress(): compression level (12) must be within -1..9 in ...
Попытка сжать пустую строку

Функция возвращает пустую строку, что можно спутать с ошибкой.

$result = gzcompress("");
var_dump($result);
string(0) ""
Использование неверной пары сжатие/распаковка

Данные, сжатые gzcompress, нельзя распаковать gzinflate.

$compressed = gzcompress("test");
$decompressed = gzinflate($compressed);
var_dump($decompressed);
Warning: gzinflate(): data error in ...
bool(false)
Сжатие некорректных данных

Передача нестрокового аргумента вызывает ошибку.

$compressed = gzcompress([1, 2, 3]);
Warning: gzcompress() expects parameter 1 to be string, array given in ...
Изменения в версиях PHP

В PHP 8.0.0 параметр $level стал обязательным, но сохранил значение по умолчанию -1. Ранее он был необязательным без явного указания значения по умолчанию в сигнатуре.

До PHP 7.0.15 и 7.1.1, при использовании уровня сжатия 0, функция могла некорректно обрабатывать некоторые данные.

Константа ZLIB_ENCODING_GZIP была добавлена в PHP 7.0.0, что позволило использовать gzcompress для создания данных в формате GZIP.

Расширенные примеры
Сжатие сериализованных данных

Эффективное сжатие структур данных PHP перед сохранением.

Пример php
$array = range(1, 1000);
$serialized = serialize($array);
$compressed = gzcompress($serialized, 9);
echo 'Без сжатия: ' . strlen($serialized) . ' байт<br>';
echo 'Со сжатием: ' . strlen($compressed) . ' байт<br>';
echo 'Экономия: ' . round((1 - strlen($compressed)/strlen($serialized)) * 100, 2) . '%';
Без сжатия: 14890 байт
Со сжатием: 287 байт
Экономия: 98.07%
Инкрементальное сжатие больших данных

Сжатие данных по частям при ограниченной памяти.

Пример php
function compressLargeData($filename) {
    $handle = fopen($filename, 'r');
    $compressedParts = [];
    while (!feof($handle)) {
        $chunk = fread($handle, 8192);
        if ($chunk !== false && $chunk !== '') {
            $compressedParts[] = gzcompress($chunk, 1); // Быстрое сжатие
        }
    }
    fclose($handle);
    return implode('', $compressedParts);
}
// Пример вызова (требуется файл для теста)
// $result = compressLargeData('large_log.txt');
Работа с бинарными данными

Сжатие содержимого файла изображения (хотя для готовых изображений это неэффективно).

Пример php
$binaryData = file_get_contents('image.png');
$compressed = gzcompress($binaryData, 9);
// Для проверки распакуем
$uncompressed = gzuncompress($compressed);
echo 'Исходный файл: ' . strlen($binaryData) . ' байт<br>';
echo 'Сжатый: ' . strlen($compressed) . ' байт<br>';
echo 'Целостность: ' . ($binaryData === $uncompressed ? 'OK' : 'ERROR');
Исходный файл: 12405 байт
Сжатый: 12422 байт
Целостность: OK
Создание собственного формата с метаданными

Добавление заголовка к сжатым данным для идентификации.

Пример php
function myCompress($data, $level = -1) {
    $compressed = gzcompress($data, $level);
    $header = pack('N', strlen($data)) . pack('C', $level);
    return $header . $compressed;
}
function myUncompress($packedData) {
    $originalSize = unpack('N', substr($packedData, 0, 4))[1];
    $level = unpack('C', substr($packedData, 4, 1))[1];
    $compressed = substr($packedData, 5);
    return gzuncompress($compressed);
}
$data = "Important data";
$packed = myCompress($data, 9);
$unpacked = myUncompress($packed);
echo "Распаковано: $unpacked";
Распаковано: Important data
Сравнение эффективности для разных типов данных

Сжатие текста, JSON и случайных данных.

Пример php
$samples = [
    'text' => str_repeat("Lorem ipsum dolor sit amet ", 100),
    'json' => json_encode(array_fill(0, 100, ['id' => rand(), 'name' => 'test'])),
    'random' => random_bytes(5000)
];
foreach ($samples as $type => $data) {
    $compressed = gzcompress($data, 6);
    $ratio = strlen($compressed) / strlen($data) * 100;
    echo "$type: исходно " . strlen($data) . " байт, сжато " . strlen($compressed) . " байт ($ratio%)<br>";
}
text: исходно 2700 байт, сжато 119 байт (4.41%)
json: исходно 3700 байт, сжато 447 байт (12.08%)
random: исходно 5000 байт, сжато 5019 байт (100.38%)

PHP gzcompress function comments

En
Gzcompress Compress a string