PHP Conference Nagoya 2025

inflate_add

(PHP 7, PHP 8)

inflate_addИнкрементальное распаковать закодированные данные

Описание

inflate_add(InflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false

Инкрементальное распаковывает закодированные данные в указанном контексте context.

Ограничение: информация заголовка из сжатых данных GZIP не доступны.

Список параметров

context

Контекст, созданный с помощью inflate_init().

data

Блок сжатых данных.

flush_mode

Одна из констант: ZLIB_BLOCK, ZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH (по умолчанию), ZLIB_FULL_FLUSH, ZLIB_FINISH. Обычно требуется установить ZLIB_NO_FLUSH для максимальной компрессии и ZLIB_FINISH для завершения работы с последним блоком данных. Детальное описание констант смотрите в » руководство zlib.

Возвращаемые значения

Возвращает блок распакованных данных или false, если возникла ошибка.

Ошибки

Если переданы некорректные параметры, распаковка требует наличие словаря, но он не задан, поток сжатых данных испорчен или имеет некорректную контрольную сумму, то генерируется ошибка уровня E_WARNING.

Список изменений

Версия Описание
8.0.0 context ожидает экземпляр InflateContext; раньше, ожидался ресурс (resource).

Смотрите также

  • inflate_init() - Инициализация контекста инкрементальной распаковки
Добавить

Примечания пользователей 1 note

up
0
burp at -only-in-German-fuerspam dot de
1 year ago
It's not obvious how to use this for _incremental_ decompression:
You feed _the compressed data_ into inflate_add() _in pieces_.
The internal state of the zlib context will make sure than you can split at any point and still get the correct total data out, as long as you keep reading until the end.

In this way, you don't have to hold the complete uncompressed data in memory at any one time (and don't have to materialize it either as a file for gzopen() etc.), allowing you to parse files much bigger than the available php memory limit.

<?php
/* a good step size depends on the input's level of compression,
unfortunately there's no obvious way to know that beforehand;
in doubt instead choose a rather small value and glue the pieces together,
until there's enough data for processing */
$step = 500000;

$dataGz = load_gzip_compressed_data_to_string();

$start = 0;
$outLen = 0;
$ctxt = inflate_init(ZLIB_ENCODING_GZIP);
$status = inflate_get_status($inflCtxt);

while(
$status == ZLIB_OK) {
$split = substr($dataGz, $start, $step);
$dataFragment = inflate_add($inflCtxt, $split);
/* process fragment, potentially keep parts across iterations */
$outLen += strlen($dataFragment);
$status = inflate_get_status($inflCtxt);
$start += $step;
}
echo
'Input: ' . strlen($dataGz) . ' Bytes / Output: ' . $outLen . ' Bytes.';
?>

N.B.: Archives of extremely high compression will still bomb out with a stupid and unnecessary memory exhaustion, as it's not possible to define a limit in inflate_init() similar to gzuncompress().
To Top