Gzencode: примеры (PHP)
gzencode(string $data, int $level = -1, int $encoding_mode = FORCE_GZIP): string|falseОсновы функции gzencode
Функция gzencode() в PHP применяется для сжатия строки с использованием алгоритма GZIP. Это полезно при уменьшении объема данных перед передачей по сети или сохранением. Сжатие соответствует формату, описанному в RFC 1952.
Функция часто используется для динамического сжатия контента веб-страниц перед отправкой браузеру, что поддерживается заголовком HTTP Content-Encoding: gzip. Также она подходит для сжатия данных перед записью в файл или базу данных.
$data (string): Исходная строка для сжатия.
$level (int, необязательный): Уровень сжатия от -1 до 9. -1 означает уровень по умолчанию zlib (обычно 6), 0 – без сжатия, 1 – минимальное сжатие (быстро), 9 – максимальное сжатие (медленно).
$encoding (int, необязательный): Константа, определяющая кодировку. FORCE_GZIP (по умолчанию) или FORCE_DEFLATE (для вывода в формате DEFLATE, совместимом с RFC 1951).
Короткие примеры использования
Сжатие строки с параметрами по умолчанию.
$data = 'Это тестовая строка для сжатия. Она повторяется. ' . str_repeat('Повтор. ', 10);
$compressed = gzencode($data);
echo 'Размер исходных данных: ' . strlen($data) . ' байт.\n';
echo 'Размер сжатых данных: ' . strlen($compressed) . ' байт.';Размер исходных данных: 112 байт. Размер сжатых данных: 71 байт.
Сравнение скорости и степени сжатия.
$data = file_get_contents('large_text.txt');
$levels = [0, 1, 6, 9];
foreach ($levels as $level) {
$start = microtime(true);
$compressed = gzencode($data, $level);
$time = microtime(true) - $start;
echo "Уровень $level: размер " . strlen($compressed) . ", время {$time}с
";
}Уровень 0: размер 110250, время 0.001с Уровень 1: размер 54321, время 0.005с Уровень 6: размер 52108, время 0.008с Уровень 9: размер 52097, время 0.012с
$data = 'Данные для сжатия в формате DEFLATE.';
$deflated = gzencode($data, 6, FORCE_DEFLATE);
echo bin2hex(substr($deflated, 0, 10));789c4b564a2e29
Похожие функции в PHP
Сжимает строку с использованием алгоритма DEFLATE (RFC 1951) без заголовков GZIP. Результат меньше, но не является полноценным GZIP-файлом. Подходит для внутреннего сжатия данных.
Использует формат ZLIB (RFC 1950), добавляя другой заголовок. Часто используется в сетевых протоколах. По умолчанию уровень сжатия -1.
Функции для поточной работы с GZIP-файлами. Позволяют сжимать данные непосредственно при записи в файл, не загружая все в память.
gzencode() применяется для создания данных в формате GZIP, например, для HTTP-ответов или файлов .gz. gzdeflate() подходит для внутреннего сжатия, когда важен минимальный размер. gzcompress() используется при работе с ZLIB-потоками.
Аналоги в других языках
import gzip
data = b'Test data for compression.'
compressed = gzip.compress(data, compresslevel=6)
print(f'Original: {len(data)}, Compressed: {len(compressed)}')Original: 25, Compressed: 49
const zlib = require('zlib');
const data = 'Test data for compression.';
zlib.gzip(data, (err, compressed) => {
if (!err) console.log(`Original: ${data.length}, Compressed: ${compressed.length}`);
});Original: 25, Compressed: 41
SELECT LENGTH(COMPRESS('Test data for compression.')) AS compressed_size;compressed_size: 39
В Python и JavaScript сжатие часто асинхронное. MySQL сохраняет данные в бинарном формате, совместимом с COMPRESS()/UNCOMPRESS(). PHP функция gzencode выдает чистый GZIP-формат, включая заголовок и контрольную сумму.
Типичные ошибки
Передача значения вне диапазона -1..9 приводит к предупреждению и использованию уровня по умолчанию.
$result = gzencode('data', 12);
echo $result ? 'Сжато' : 'Ошибка';Warning: gzencode(): compression level (12) must be within -1..9 in ... Сжато
Сжатие бинарных строк работает корректно, но результат тоже бинарный. Его нужно правильно обрабатывать (например, использовать base64_encode для передачи в текстовых средах).
$binary = file_get_contents('image.jpg');
$compressed = gzencode($binary, 9);
// Попытка вывести как текст вызовет проблемы
// echo $compressed; // Не делайте такСжатие пустой строки возвращает непустые данные (заголовок GZIP).
$result = gzencode('');
echo 'Длина: ' . strlen($result);Длина: 20
Изменения в PHP
В PHP 8.0.0 параметр $level стал опциональным (ранее был обязательным). Значение по умолчанию изменилось с -1 (уровень по умолчанию zlib) на -1 (но теперь его можно опустить). Поведение функции осталось прежним. В более ранних версиях, начиная с PHP 4.0.4, доступны константы FORCE_GZIP и FORCE_DEFLATE.
Расширенные примеры
Динамическое сжатие HTML-контента с проверкой поддержки браузером.
if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', 'gzip') !== false) {
ob_start('ob_gzhandler');
echo 'Большой HTML-контент...';
ob_end_flush();
} else {
echo 'Большой HTML-контент...';
}Сохранение сжатых данных в файл с расширением .gz.
$content = "Лог-данныен" . str_repeat("Строка лога.\n", 1000);
$compressed = gzencode($content, 9);
file_put_contents('archive.log.gz', $compressed);
// Для распаковки: gunzip archive.log.gzСжатие данных по частям для экономии памяти.
function compressLargeData($filename, $chunkSize = 8192) {
$dest = fopen($filename . '.gz', 'wb');
$src = fopen($filename, 'rb');
$level = 6;
// Пишем заголовок GZIP вручную (упрощенно)
fwrite($dest, gzencode('', $level)); // Получаем заголовок из пустой строки
fseek($dest, -8, SEEK_END); // Перемещаемся перед CRC32 и размером
$crc = 0;
$totalLen = 0;
while (!feof($src)) {
$chunk = fread($src, $chunkSize);
$totalLen += strlen($chunk);
$crc = crc32($chunk, $crc);
$compressedChunk = gzencode($chunk, $level, FORCE_DEFLATE); // Без заголовка
// Убираем заголовок DEFLATE (первые 2 байта) и конечные 4 байта Adler-32
$deflateData = substr($compressedChunk, 2, -4);
fwrite($dest, $deflateData);
}
// Записываем CRC32 и исходный размер (младший байт первый)
fwrite($dest, pack('V', $crc) . pack('V', $totalLen));
fclose($src);
fclose($dest);
}
// compressLargeData('large_file.txt');$samples = [
'text' => str_repeat('Текст с избыточностью. ', 100),
'json' => json_encode(range(1, 1000)),
'binary' => random_bytes(1000)
];
foreach ($samples as $type => $data) {
$compressed = gzencode($data, 6);
$ratio = round(strlen($compressed) / strlen($data) * 100, 1);
echo "$type: коэффициент сжатия {$ratio}%
";
}text: коэффициент сжатия 14.5% json: коэффициент сжатия 7.2% binary: коэффициент сжатия 100.3%