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

Руководство по работе с функцией 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с
Использование FORCE_DEFLATE
$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.

gzopen() / gzwrite()

Функции для поточной работы с GZIP-файлами. Позволяют сжимать данные непосредственно при записи в файл, не загружая все в память.

Выбор функции

gzencode() применяется для создания данных в формате GZIP, например, для HTTP-ответов или файлов .gz. gzdeflate() подходит для внутреннего сжатия, когда важен минимальный размер. gzcompress() используется при работе с ZLIB-потоками.

Аналоги в других языках

Python: модуль gzip
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
JavaScript (Node.js): zlib module
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
MySQL: COMPRESS()
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.

Расширенные примеры

Сжатие для HTTP-ответа

Динамическое сжатие HTML-контента с проверкой поддержки браузером.

Пример php
if (strpos($_SERVER['HTTP_ACCEPT_ENCODING'] ?? '', 'gzip') !== false) {
    ob_start('ob_gzhandler');
    echo 'Большой HTML-контент...';
    ob_end_flush();
} else {
    echo 'Большой HTML-контент...';
}
Создание GZIP-файла

Сохранение сжатых данных в файл с расширением .gz.

Пример php
$content = "Лог-данныен" . str_repeat("Строка лога.\n", 1000);
$compressed = gzencode($content, 9);
file_put_contents('archive.log.gz', $compressed);
// Для распаковки: gunzip archive.log.gz
Поточное сжатие больших данных

Сжатие данных по частям для экономии памяти.

Пример php
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');
Сравнение эффективности для разных типов данных
Пример php
$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%

PHP gzencode function comments

En
Gzencode Create a gzip compressed string