Gzinflate: примеры (PHP)
gzinflate(string $data, int $max_length = 0): string|falseФункция gzinflate() используется для распаковки строки данных, сжатых алгоритмом DEFLATE (RFC 1951). Этот алгоритм является основой для форматов сжатия, таких как gzip (RFC 1952) и zlib (RFC 1950). Функция часто применяется при работе с сетевыми протоколами, обработке сжатых ответов серверов или распаковке данных, сохраненных в сжатом виде для экономии места.
Функция принимает два аргумента:
- string $data - Сжатая строка для распаковки.
- int $max_length = 0 (необязательный) - Максимальный размер распакованных данных. Если указан 0 или опущен, функция будет распаковывать данные до их исходного размера. На практике для безопасности рекомендуется устанавливать этот лимит.
Функция возвращает распакованную строку или FALSE в случае ошибки.
// Сначала сжимаем строку с помощью gzdeflate
$compressed = gzdeflate('Исходные данные для сжатия.', 9);
echo 'Сжатая строка (base64): ' . base64_encode($compressed) . "\n";
// Распаковываем обратно
$uncompressed = gzinflate($compressed);
echo 'Распаковано: ' . $uncompressed;
Сжатая строка (base64): c87PTc3LLFYoSQWyigoSkxXS85KTS3KKFSDcoqLMvBQgFwA= Распаковано: Исходные данные для сжатия.
$data = 'Очень длинная строка, которую нужно сжать.';
$compressed = gzdeflate($data);
// Ограничим размер распаковки первыми 10 байтами
$result = gzinflate($compressed, 10);
echo $result;
Очень длин
- gzuncompress() - Распаковывает строку, сжатую с помощью алгоритма zlib (RFC 1950). Данные должны иметь заголовок zlib. Функция gzinflate() работает с "сырым" DEFLATE-потоком без заголовка.
- gzdecode() - Распаковывает строку, сжатую в формате gzip (RFC 1952). Этот формат включает заголовок с метаданными (например, оригинальное имя файла).
- inflate_init() и inflate_add() (PHP 7 >= 7.2.0) - Позволяют инкрементально распаковывать данные по частям, что полезно для работы с большими потоками.
Выбор функции зависит от формата сжатых данных: используйте gzinflate() для "сырого" DEFLATE, gzuncompress() для zlib и gzdecode() для gzip.
Gzinflate в Python
Модуль zlib предоставляет функцию decompress() с возможностью указания формата (wbits). Для "сырого" DEFLATE используется константа -zlib.MAX_WBITS.
import zlib, base64
compressed_data = base64.b64decode('c87PTc3LLFYoSQWyigoSkxXS85KTS3KKFSDcoqLMvBQgFwA=')
decompressed = zlib.decompress(compressed_data, -zlib.MAX_WBITS)
print(decompressed.decode('utf-8'))
Исходные данные для сжатия.
Модуль zlib содержит метод inflateRaw() для работы с DEFLATE без заголовка.
const zlib = require('zlib');
const compressed = Buffer.from('c87PTc3LLFYoSQWyigoSkxXS85KTS3KKFSDcoqLMvBQgFwA=', 'base64');
zlib.inflateRaw(compressed, (err, result) => {
if (!err) console.log(result.toString());
});
Исходные данные для сжатия.
$result = gzinflate('Некорректные данные');
var_dump($result);
bool(false)
Функция возвращает FALSE. Необходимо проверять результат с помощью оператора ===.
// Пытаемся распаковать zlib-данные через gzinflate
$zlibCompressed = gzcompress('test'); // Создает zlib-формат
$result = gzinflate($zlibCompressed);
var_dump($result);
bool(false)
Для zlib-данных следует использовать gzuncompress().
$compressed = gzdeflate('Длинная строка');
$result = gzinflate($compressed, 1); // Слишком маленький лимит
echo $result === false ? 'Ошибка' : $result;
Ошибка
- В PHP 7.0.15 и 7.1.1 исправлена ошибка, из-за которой gzinflate() могла некорректно обрабатывать данные при использовании параметра max_length.
- В PHP 8.0 функция теперь выбрасывает ошибку уровня E_WARNING в случае неудачи (ранее молча возвращала FALSE). Это соответствует общей тенденции PHP 8 к более строгой обработке ошибок.
- Сам алгоритм и сигнатура функции остаются стабильными на протяжении многих версий.
// Сжатие и распаковка бинарных данных (например, сериализованного массива)
$originalData = serialize([1, 2, 3, 'test' => 'value']);
$compressedBinary = gzdeflate($originalData);
$uncompressedBinary = gzinflate($compressedBinary);
$restoredArray = unserialize($uncompressedBinary);
print_r($restoredArray);
Array
(
[0] => 1
[1] => 2
[2] => 3
[test] => value
)
// Полезно при чтении больших сжатых потоков по частям
$resource = inflate_init(ZLIB_ENCODING_RAW);
$chunk1 = gzdeflate('Первая часть ');
$chunk2 = gzdeflate('и вторая часть.');
$result = inflate_add($resource, $chunk1);
$result .= inflate_add($resource, $chunk2, ZLIB_FINISH);
echo $result;
Первая часть и вторая часть.
try {
$result = gzinflate('broken');
if ($result === false) {
throw new ValueError('Ошибка распаковки данных');
}
} catch (ValueError $e) {
echo 'Перехвачена ошибка: ' . $e->getMessage();
}
Перехвачена ошибка: Ошибка распаковки данных
// Имитация получения сжатых данных по сети (HTTP с Content-Encoding: deflate)
// Предположим, что это "сырой" DEFLATE, как иногда бывает в старых API
$httpBody = file_get_contents('https://example.com/api/deflate-data');
// Убираем возможные заголовки, если они есть
$deflateData = substr($httpBody, 2); // Эвристика, зависит от специфики API
$usableData = gzinflate($deflateData);
echo substr($usableData, 0, 100);