Перейти к содержимому
Поиск
Php Разработка

PHP: полный мануал с примерами, функциями и ООП

Практический мануал PHP: от переменных и читаемого кода до безопасных форм, интеграций, базы данных и ООП на примере магазина. Учебный маршрут, поиск функций, подробные примеры, разбор ошибок и исходники для скачивания.

Александр НекрасовИзменено:
Практический мануал PHP: от переменных и функций к объектной модели интернет-магазина
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 104 · От основ к практике

Zlib: gzip-файлы, сжатие строк и потоков

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

Отчёт стал большим: уменьшаем байты, сохраняя исходные данные

Наглядная модель

Текст остаётся тем же, меняется его упаковка

Отчёт READY сжимается перед хранением или передачей. Получатель должен знать формат и проверить результат распаковки.

  1. $text = READY

    Обычные исходные байты; их смысл известен приложению.

  2. gzencode($text)

    Получается бинарный поток формата gzip с собственной оболочкой.

  3. Хранение или передача

    Сжатые байты не преобразуют как обычный текст и не называют ZIP-архивом.

  4. gzdecode → READY

    Проверяем false, размер и точное восстановление ожидаемых данных.

Сжатие не шифрует. Короткий READY может стать больше из-за заголовков; большой распакованный результат требует отдельных ограничений памяти и времени.

Магазин каждый день передаёт поставщику текстовый отчёт. В нём повторяются имена полей и похожие строки. Сжатие кодирует эти повторы компактнее; получатель должен применить подходящую распаковку и получить тот же текст. Это полезно для обмена и хранения, но не скрывает данные от посторонних.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Один и тот же смысл в двух представлениях
  1. Исходный текст: READY
  2. Компрессор → бинарные байты
  3. Передача/хранение по договорённому формату
  4. Декомпрессор → снова READY
Сжать и восстановить одну строкуСамостоятельный пример
<?php
declare(strict_types=1);

$text = 'READY';
$packed = gzencode($text);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
$restored = gzdecode($packed);
if ($restored === false) { throw new RuntimeException('Decompression failed'); }
echo $restored, "\n";
var_dump($restored === $text);
Ожидаемый результат
READY
bool(true)

text — исходная строка, packed — сжатые байты, restored — восстановленная строка. Короткий READY может занимать после сжатия больше места: у формата есть служебные поля.

Не нужно учить все функции сразу. Сначала определите, что у вас есть: строка в памяти, файл .gz, поступающие части или HTTP-ответ. В конце главы находится полный указатель всех31функций, включая удалённую историческую gzgetss.

Gzip, zlib, raw DEFLATE и ZIP — разные договоры

Формат — оболочка вокруг алгоритма
  1. DEFLATE сжимает данные
  2. Raw: только поток DEFLATE
  3. Zlib: своя оболочка/контроль
  4. Gzip: другая оболочка/контроль
ФорматСжать → распаковатьГде встречается
Gzip RFC1952gzencode → gzdecode.gz, HTTP Content-Encoding:gzip.
Zlib RFC1950gzcompress → gzuncompressДвоичный протокол с zlib-оболочкой; HTTP deflate.
Raw DEFLATE RFC1951gzdeflate → gzinflateУчасток более сложного контейнера/протокола, который сам описывает метаданные.
Выбранный/распознаваемый форматzlib_encode / zlib_decodeЯвный encoding у компрессора; распознавание поддержанных оболочек у декодера.
ZIPZipArchive из отдельного расширенияКонтейнер с именами нескольких файлов, каталогом, методами сжатия и метаданными. Ни gzcompress, ни gzencode не создают ZIP.

Добавление .zip к имени не меняет формат. Заголовок HTTP deflate тоже не превращает raw DEFLATE в zlib. Проверяйте договор получателя, а не сходство имён PHP-функций. Контрольная сумма формата обнаруживает некоторые повреждения, но не подтверждает отправителя; для подлинности нужен другой механизм.

Три формата возвращают одинаковый исходный текстСамостоятельный пример
<?php
declare(strict_types=1);

$text = 'order=25';
echo gzdecode(gzencode($text)), "\n";
echo gzuncompress(gzcompress($text)), "\n";
echo gzinflate(gzdeflate($text)), "\n";
Ожидаемый результат
order=25
order=25
order=25

Сравниваем восстановленные данные. Не требуем побайтно одинаковой упаковки разных библиотек или версий.

Выбор функции по источнику данных и размеру

ЗадачаПодходЦена/граница
Небольшая строка в памятиgzencode, gzdecodeИсходная и полученная строки занимают память одновременно.
Построчный файлgzopen + gzgets + gzcloseНеограниченно длинная строка всё равно может занять много памяти.
Бинарный/большой файлgzread / gzwriteПроверять длину, false, отсутствие прогресса и общий бюджет.
Весь небольшой файл как массивgzfileУдобно, но весь распакованный текст и массив уже в памяти.
Поток частями из сетиdeflate_init/deflate_add и inflate_init/inflate_addСохранять context, проверять конец потока; один chunk может дать большой результат.
Выдать .gz в распакованном видеreadgzfile / gzpassthruВыводят данные напрямую, возвращают число байтов.
Сжать динамический HTTP-ответОдин слой сервера/proxy либо PHP zlib.output_compressionНе сжимать повторно, проверять реальные заголовки/тело и политику кэша.

Последовательная обработка большого файла обычно понятнее случайных прыжков: gzseek может повторно распаковывать пройденные данные и быть медленной. Экономия памяти требует не только читать порциями, но и не собирать их затем в одну огромную строку.

Память не освобождается от одного слова «поток»
  1. Прочитали маленький chunk
  2. Если дописывать его в общий result, result растёт
  3. Если обработать и освободить — остаётся рабочая порция
  4. Внутренние буферы и размер раскрытия тоже учитываются

Установка, требования и проверка своего PHP

Расширение использует библиотеку zlib. Для PHP8.4+ официально требуется zlib не ниже1.2.11; раньше минимумом была1.2.0.4. При сборке Unix включают --with-zlib[=DIR]; это параметр сборки PHP, не функция приложения. В Windows-поставке PHP поддержка встроена, отдельный DLL для этих функций обычно не загружается. Наличие PHP само по себе всё же лучше проверить на конкретном сервере.

Проверка возможностей до первой интеграции
  1. Проверить extension_loaded zlib
  2. Посмотреть фактическую версию библиотеки
  3. Выполнить маленький round-trip
  4. Отдельно проверить HTTP/FS контекст своей системы
Проверить библиотеку без изменения конфигурацииСамостоятельный пример
<?php
declare(strict_types=1);

var_dump(extension_loaded('zlib'));
var_dump(is_string(ZLIB_VERSION), is_int(ZLIB_VERNUM));
echo gzdecode(gzencode('test')), "\n";
Ожидаемый результат
bool(true)
bool(true)
bool(true)
test

В авторской проверке PHP8.5.11 использует zlib1.3.2. В другом окружении версия может отличаться; документируйте её, особенно при расследовании поведения и переносе бинарного формата.

Composer не заменяет системное расширение. Веб-PHP и CLI могут читать разные ini. Библиотека не даёт автоматически права записи в каталог, сетевой доступ или корректные HTTP-заголовки.

Все три настройки автоматического сжатия вывода

Директива / defaultЧто регулируетГраница
zlib.output_compression = 0, INI_ALLВключить прозрачное сжатие; On/Off либо целое значение размера буфера, обычный default-буфер4KiB.Менять до отправки вывода. Добавляет Content-Encoding и Vary:Accept-Encoding при подходящем кодировании.
zlib.output_compression_level = -1, INI_ALLУровень0..9; −1 оставляет стандартный выбор zlib.0 не сжимает данные алгоритмически, но контейнер/служебная обработка всё ещё имеют цену. Более высокий уровень не гарантирует меньшего времени запроса.
zlib.output_handler = "", INI_ALLСпециальная точка настройки обработчика в согласованном порядке с zlib.При zlib.output_compression обычный output_handler должен быть пустым. Не подключайте произвольные конкурирующие обработчики; проверьте порядок и совместимость.

Не включайте ob_gzhandler одновременно с zlib.output_compression. INI_ALL означает разрешённые уровни настройки, но не разрешает менять уже отправленные заголовки. В приложении проверяйте результат ini_set. Разбор HTTP-весов Accept-Encoding в PHP8.5.11 ограничен поиском подстрок — это подробно показано в ob_gzhandler.

Один ответ — один ответственный за кодирование
  1. Проверить proxy/web-server
  2. Выбрать слой сжатия
  3. Настроить до отправки тела
  4. Клиент проверяет заголовки и декодируемость

Все константы: формат, стратегия, завершение и статус

ГруппаЗначения и смысл
ФорматZLIB_ENCODING_RAW — RFC1951; ZLIB_ENCODING_DEFLATE — RFC1950; ZLIB_ENCODING_GZIP — RFC1952. FORCE_DEFLATE и FORCE_GZIP — старые имена для выбора zlib/gzip, а не raw.
СтратегияZLIB_DEFAULT_STRATEGY — обычный выбор; ZLIB_FILTERED — данные после фильтра; ZLIB_HUFFMAN_ONLY — только кодирование Хаффмана; ZLIB_RLE — акцент на сериях; ZLIB_FIXED — фиксированные коды. Это настройки deflate, не криптографические режимы.
FlushZLIB_NO_FLUSH, ZLIB_PARTIAL_FLUSH, ZLIB_SYNC_FLUSH, ZLIB_FULL_FLUSH, ZLIB_BLOCK, ZLIB_FINISH. FINISH завершает поток; FULL_FLUSH сбрасывает историю и может ухудшить сжатие.
ВерсияZLIB_VERSION — строка версии; ZLIB_VERNUM — целочисленное представление версии библиотеки.
Успех/конецZLIB_OK — обычное состояние; ZLIB_STREAM_END — корректно достигнут конец. Непустой результат inflate_add ещё не равен STREAM_END.
СловарьZLIB_NEED_DICT — нужен согласованный предварительный словарь.
ОшибкиZLIB_ERRNO — ошибка файловой операции; ZLIB_STREAM_ERROR — неверное состояние/параметр; ZLIB_DATA_ERROR — повреждённые данные; ZLIB_MEM_ERROR — недостаток памяти; ZLIB_BUF_ERROR — нет прогресса/не хватает входа или пространства; ZLIB_VERSION_ERROR — несовместимая версия библиотеки.
Проверять не только полученную строку
  1. inflate_add может дать часть текста
  2. inflate_get_status сообщает состояние
  3. Только STREAM_END подтверждает конец этого потока
  4. Размер, остаток и бизнес-формат проверяются отдельно

Таблица перечисляет все27констант официальной страницы. Не каждый код обязательно достижим из любого PHP-вызова. Используйте имена, не случайно запомненные числа. Все режимы flush и опции контекста разобраны в deflate_add и deflate_init.

Поток файла и контекст компрессора — разные виды состояния

gzopen возвращает файловый resource; его закрывают gzclose. deflate_init/inflate_init с PHP8 возвращают специальные объекты; до PHP8 они возвращали zlib.deflate/zlib.inflate resource. Их не передают gzclose и не редактируют как массив. Объект контекста хранит историю алгоритма, файловый ресурс ещё связан с файлом и позицией. Для gzip-файлов существует также fopen-обёртка compress.zlib://; её протокол описан в официальной главе обёрток сжатия. gz-файловый API работает с файлами, не заменяет сокетный протокол; для получаемых из сети частей используйте контекстный API.

Не перепутать дескрипторы
  1. gzopen → ресурс файла
  2. deflate_init → DeflateContext
  3. inflate_init → InflateContext
  4. Каждому виду — собственные функции

Контексты не являются переносимой формой задания для очереди. В очередь передают данные/параметры и создают новый контекст в worker. Закрытие файла и потеря ссылки на контекст — разные механизмы освобождения.

DeflateContext: непрозрачный объект состояния, создаваемый фабрикой

Это final-класс встроенного расширения, введённый в PHP8. Он не описывает вашу бизнес-сущность и не предназначен для наследования. Публичный new не создаёт рабочий контекст; используйте deflate_init. В классе нет пользовательского набора методов/полей для ручной настройки; функции принимают сам объект.

Один поток — одно согласованное состояние
  1. Фабрика deflate_init
  2. Получен DeflateContext
  3. Вызовы deflate_add продолжают работу
  4. Новый независимый документ → новое осознанное состояние
Создать контекст через предназначенную функциюСамостоятельный пример
<?php
declare(strict_types=1);

$context = deflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
echo get_class($context), "
";
Ожидаемый результат
DeflateContext

Не вызываем new. Если фабрика отказала, false нельзя передавать в add.

Проверить границы непрозрачного состоянияСамостоятельный пример
<?php
declare(strict_types=1);

$context = deflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
try { $copy = clone $context; }
catch (Error $error) { echo "clone unavailable
"; }
try { serialize($context); }
catch (Exception $error) { echo "serialization unavailable
"; }
try { $context->label = 'report'; }
catch (Error $error) { echo "dynamic properties unavailable
"; }
Ожидаемый результат
clone unavailable
serialization unavailable
dynamic properties unavailable

PHP8.5.11 запрещает эти операции. Собственные метаданные храните в отдельной структуре/объекте приложения, не внутри C-контекста.

Присваивание второй переменной не клонирует объект: обе ссылаются на одно состояние. Если хотите независимое сжатие/распаковку, создайте другой контекст с тем же договором. Это практическая связь с объектами и ссылками и присваиванием.

InflateContext: непрозрачный объект состояния, создаваемый фабрикой

Это final-класс встроенного расширения, введённый в PHP8. Он не описывает вашу бизнес-сущность и не предназначен для наследования. Публичный new не создаёт рабочий контекст; используйте inflate_init. В классе нет пользовательского набора методов/полей для ручной настройки; функции принимают сам объект.

Один поток — одно согласованное состояние
  1. Фабрика inflate_init
  2. Получен InflateContext
  3. Вызовы inflate_add продолжают работу
  4. Новый независимый документ → новое осознанное состояние
Создать контекст через предназначенную функциюСамостоятельный пример
<?php
declare(strict_types=1);

$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
echo get_class($context), "
";
Ожидаемый результат
InflateContext

Не вызываем new. Если фабрика отказала, false нельзя передавать в add.

Проверить границы непрозрачного состоянияСамостоятельный пример
<?php
declare(strict_types=1);

$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
try { $copy = clone $context; }
catch (Error $error) { echo "clone unavailable
"; }
try { serialize($context); }
catch (Exception $error) { echo "serialization unavailable
"; }
try { $context->label = 'report'; }
catch (Error $error) { echo "dynamic properties unavailable
"; }
Ожидаемый результат
clone unavailable
serialization unavailable
dynamic properties unavailable

PHP8.5.11 запрещает эти операции. Собственные метаданные храните в отдельной структуре/объекте приложения, не внутри C-контекста.

Присваивание второй переменной не клонирует объект: обе ссылаются на одно состояние. Если хотите независимое сжатие/распаковку, создайте другой контекст с тем же договором. Это практическая связь с объектами и ссылками и присваиванием.

Повреждённый вход, слишком большой результат и целостность

Сжатые данные — бинарные. BOM, HTML-предупреждение PHP перед ними, перевод кодировки или запись через неподходящую текстовую обработку портят поток. При ошибке сначала сравните реальные байты транспорта и согласованный формат. Нельзя без договора отрезать всё до первого похожего заголовка: можно скрыть ошибку сервера или принять не тот документ.

Защита состоит из нескольких проверок
  1. Ограничить вход и время
  2. Выбрать согласованный формат
  3. Проверить отказ/завершение и размер выхода
  4. Проверить структуру JSON/CSV и бизнес-правила

В PHP8.5.11/zlib1.3.2 max_length у строковых декодеров в некоторых случаях превышается:48байт результата могут вернуться при лимите47. В карточках есть воспроизводимый пример и постпроверка strlen. Постпроверка выявляет превышение, но не отменяет память, уже выделенную декодером. Для недоверенного сжатого входа нужен также процессный бюджет, лимит входа/времени и архитектура с контролем ресурсов.

inflate_add может выдать часть полезного текста даже для усечённого потока. Проверяйте ZLIB_STREAM_END, остаток входа, количество разрешённых members и checksum по договору. gzeof сам по себе допускает состояние ошибки. Префикс1F8B или расширение.gz не подтверждает ни полную распаковку, ни безопасность содержимого.

Сжатие не шифрует и не заменяет проверку подлинности. Повторная упаковка уже сжатого файла часто тратит CPU без пользы. Измеряйте полный путь — чтение, сжатие, передачу, распаковку, запись — на типичных данных.

Практика: сжатая выгрузка из магазина

Учебная задача от малого к большому
  1. Строка READY → gzip → та же строка
  2. Две строки заказа → файл.gz
  3. Построчное чтение → обработка каждой записи
  4. Поток интеграции → проверка окончания и лимитов

Первый шаг: повторите небольшой round-trip и сравните строки строго. Второй: создайте две строки отчёта через gzopen/gzwrite, проверьте числа записанных байтов и закрытие. Третий: прочитайте их gzgets, сохраняя значения0 и различая конец/ошибку. Четвёртый: передайте те же данные частями через deflate_add и убедитесь в STREAM_END у получателя.

Критерий результата: получатель видит ровно исходные данные, ошибка формата не превращается в пустой успех, большой файл не собирается без необходимости целиком, и ясно, какой слой сжимает HTTP. Полные самостоятельные примеры находятся в карточках; они расширяют оба официальных примера zlib — запись/повторное чтение файла и инкрементальный поток.

Все31функции категории Zlib

ФункцияПрактическая задача
deflate_addДобавить очередные данные в контекст и получить созданную на этом шаге сжатую часть.
deflate_initПодготовить сжатие больших данных порциями, сохраняя историю повторений между частями.
gzcloseЗакрыть gz-поток, завершить запись и освободить связанный файловый ресурс.
gzcompressСжать готовую строку в формате zlib для хранения или обмена с получателем, который ожидает именно этот формат.
gzdecodeВосстановить строку из gzip и явно отличить испорченный поток от корректного пустого результата.
gzdeflateСжать готовую строку в формате raw DEFLATE для хранения или обмена с получателем, который ожидает именно этот формат.
gzencodeСжать готовую строку в формате gzip для хранения или обмена с получателем, который ожидает именно этот формат.
gzeofУзнать, достиг ли gz-поток конца либо состояния ошибки.
gzfileЗагрузить весь распакованный текст gzip-файла в массив строк.
gzgetcПрочитать один распакованный байт; удобно разбирать простой ASCII-разделитель.
gzgetsПолучить строку текста из gzip-выгрузки, сохранив её перевод строки.
gzgetssПонять старый код, который читал gzip-строку и удалял HTML-теги; в PHP8 функция удалена.
gzinflateВосстановить строку из raw DEFLATE и явно отличить испорченный поток от корректного пустого результата.
gzopenОткрыть gzip-файл для чтения или записи, не собирая весь распакованный документ в памяти.
gzpassthruВывести все оставшиеся распакованные данные открытого gz-потока.
gzputsЗаписать исходные байты в gz-поток через псевдоним gzwrite.
gzreadПрочитать до заданного числа распакованных байтов с текущей позиции.
gzrewindВернуть указатель gz-потока к началу распакованных данных.
gzseekПерейти к смещению в распакованных данных gz-потока.
gztellПолучить текущую позицию в распакованных байтах.
gzuncompressВосстановить строку из zlib и явно отличить испорченный поток от корректного пустого результата.
gzwriteЗаписать исходные байты в gz-поток, получив число принятых байтов.
inflate_addПередать очередные сжатые байты декодеру и получить доступную распакованную часть.
inflate_get_read_lenУзнать, сколько сжатых входных байтов реально потребил декодер, и обнаружить хвост после первого потока.
inflate_get_statusУзнать состояние распаковки и подтвердить именно конец корректного сжатого потока.
inflate_initСоздать состояние для постепенной распаковки согласованного сжатого потока.
ob_gzhandlerПодключить штатный обработчик буфера вывода, который может сжать HTTP-ответ для клиента.
readgzfileОткрыть gzip-файл, распаковать и сразу вывести его содержимое.
zlib_decodeРаспаковать один из поддерживаемых raw/gzip/zlib форматов в инструменте, где такая вариативность действительно разрешена.
zlib_encodeВыбрать формат сжатия явным аргументом, когда один код обслуживает несколько согласованных форматов обмена.
zlib_get_coding_typeПосмотреть, какой тип кодирования выбран zlib для текущего вывода.

Функции и методы этой темы

Откройте карточку, чтобы увидеть договор функции, примеры, ограничения и связанные инструменты.

gzcompressСжать готовую строку в формате zlib для хранения или обмена с получателем, который ожидает именно этот формат.

PHP 4.0.1+ · zlib

gzcompress(string $data, int $level = -1, int $encoding = ZLIB_ENCODING_DEFLATE): string|false

Сжать готовую строку в формате zlib для хранения или обмена с получателем, который ожидает именно этот формат.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataИсходные байты строки. JSON/CSV сначала превращают в строку; массив напрямую не передают. Исходные данные и результат одновременно занимают память.
levelОт -1 до 9: -1 выбирает default библиотеки (обычно 6), 0 упаковывает без сжатия, 1..9 меняют компромисс работы и размера. 9 не обещает ускорить передачу любой маленькой строки.
encodingZLIB_ENCODING_DEFLATE по умолчанию. Текущий PHP 8.5.11 принимает все три ZLIB_ENCODING_RAW/DEFLATE/GZIP; третий аргумент способен изменить формат вопреки имени функции.
Возврат / ошибкиБинарная строка либо false при внутреннем отказе с E_WARNING. Недопустимый level/encoding вызывает ValueError в текущем PHP.
Выборgzip — формат .gz, zlib — оболочка с Adler-32, raw — поток DEFLATE без этой оболочки. Ни один из них сам по себе не является ZIP-архивом нескольких файлов.
Уменьшить повторяющийся отчёт
  1. Строка report содержит повторения
  2. Выбран формат zlib
  3. gzcompress возвращает бинарные байты
  4. gzuncompress восстанавливает исходный отчёт
Сжать и восстановить короткий отчётСамостоятельный пример
<?php
declare(strict_types=1);

$report = "order=42;status=ready";
$packed = gzcompress($report);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
$restored = gzuncompress($packed);
var_dump($restored === $report);
echo $restored, "\n";
Ожидаемый результат
bool(true)
order=42;status=ready

Проверяем точные восстановленные данные, а не жёсткий hex сжатого потока: бинарное оформление может зависеть от версии библиотеки, режима и ОС.

Проверить, окупается ли сжатие конкретных данныхСамостоятельный пример
<?php
declare(strict_types=1);

$report = str_repeat("order=42;status=ready\n", 100);
$packed = gzcompress($report, 6);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
var_dump(strlen($packed) < strlen($report));
var_dump(gzuncompress($packed) === $report);
Ожидаемый результат
bool(true)
bool(true)

В этой fixture много повторов, поэтому уменьшение заметно. Для уже сжатого изображения/случайного токена эффект будет другим. Сравнение размера не измеряет время CPU.

Обработать неверные настройкиСамостоятельный пример
<?php
declare(strict_types=1);

try { gzcompress('report', 10); }
catch (ValueError $error) { echo "Invalid level\n"; }
try { gzcompress('report', -1, 999); }
catch (ValueError $error) { echo "Invalid format\n"; }
Ожидаемый результат
Invalid level
Invalid format

Это ошибки конфигурации разработчика. Получатель должен знать формат заранее; смена третьего аргумента требует изменить парный декодер.

Байты могут содержать нули и недопустимые UTF-8 последовательности. В БД используйте подходящее бинарное поле; текстовый transport может требовать Base64 с дополнительным увеличением объёма. Не добавляйте к результату произвольный префикс без явного формата конверта. Передача бинарных данных в текстовом API показывает этот слой.

Дальше: gzuncompress; zlib_encode.

gzencodeСжать готовую строку в формате gzip для хранения или обмена с получателем, который ожидает именно этот формат.

PHP 4.0.4+ · zlib

gzencode(string $data, int $level = -1, int $encoding = ZLIB_ENCODING_GZIP): string|false

Сжать готовую строку в формате gzip для хранения или обмена с получателем, который ожидает именно этот формат.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataИсходные байты строки. JSON/CSV сначала превращают в строку; массив напрямую не передают. Исходные данные и результат одновременно занимают память.
levelОт -1 до 9: -1 выбирает default библиотеки (обычно 6), 0 упаковывает без сжатия, 1..9 меняют компромисс работы и размера. 9 не обещает ускорить передачу любой маленькой строки.
encodingZLIB_ENCODING_GZIP по умолчанию. Текущий PHP 8.5.11 принимает все три ZLIB_ENCODING_RAW/DEFLATE/GZIP; третий аргумент способен изменить формат вопреки имени функции.
Возврат / ошибкиБинарная строка либо false при внутреннем отказе с E_WARNING. Недопустимый level/encoding вызывает ValueError в текущем PHP.
Выборgzip — формат .gz, zlib — оболочка с Adler-32, raw — поток DEFLATE без этой оболочки. Ни один из них сам по себе не является ZIP-архивом нескольких файлов.
Уменьшить повторяющийся отчёт
  1. Строка report содержит повторения
  2. Выбран формат gzip
  3. gzencode возвращает бинарные байты
  4. gzdecode восстанавливает исходный отчёт
Сжать и восстановить короткий отчётСамостоятельный пример
<?php
declare(strict_types=1);

$report = "order=42;status=ready";
$packed = gzencode($report);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
$restored = gzdecode($packed);
var_dump($restored === $report);
echo $restored, "\n";
Ожидаемый результат
bool(true)
order=42;status=ready

Проверяем точные восстановленные данные, а не жёсткий hex сжатого потока: бинарное оформление может зависеть от версии библиотеки, режима и ОС.

Проверить, окупается ли сжатие конкретных данныхСамостоятельный пример
<?php
declare(strict_types=1);

$report = str_repeat("order=42;status=ready\n", 100);
$packed = gzencode($report, 6);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
var_dump(strlen($packed) < strlen($report));
var_dump(gzdecode($packed) === $report);
Ожидаемый результат
bool(true)
bool(true)

В этой fixture много повторов, поэтому уменьшение заметно. Для уже сжатого изображения/случайного токена эффект будет другим. Сравнение размера не измеряет время CPU.

Обработать неверные настройкиСамостоятельный пример
<?php
declare(strict_types=1);

try { gzencode('report', 10); }
catch (ValueError $error) { echo "Invalid level\n"; }
try { gzencode('report', -1, 999); }
catch (ValueError $error) { echo "Invalid format\n"; }
Ожидаемый результат
Invalid level
Invalid format

Это ошибки конфигурации разработчика. Получатель должен знать формат заранее; смена третьего аргумента требует изменить парный декодер.

Байты могут содержать нули и недопустимые UTF-8 последовательности. В БД используйте подходящее бинарное поле; текстовый transport может требовать Base64 с дополнительным увеличением объёма. Не добавляйте к результату произвольный префикс без явного формата конверта. Передача бинарных данных в текстовом API показывает этот слой.

Дальше: gzdecode; zlib_encode.

gzdeflateСжать готовую строку в формате raw DEFLATE для хранения или обмена с получателем, который ожидает именно этот формат.

PHP 4.0.4+ · zlib

gzdeflate(string $data, int $level = -1, int $encoding = ZLIB_ENCODING_RAW): string|false

Сжать готовую строку в формате raw DEFLATE для хранения или обмена с получателем, который ожидает именно этот формат.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataИсходные байты строки. JSON/CSV сначала превращают в строку; массив напрямую не передают. Исходные данные и результат одновременно занимают память.
levelОт -1 до 9: -1 выбирает default библиотеки (обычно 6), 0 упаковывает без сжатия, 1..9 меняют компромисс работы и размера. 9 не обещает ускорить передачу любой маленькой строки.
encodingZLIB_ENCODING_RAW по умолчанию. Текущий PHP 8.5.11 принимает все три ZLIB_ENCODING_RAW/DEFLATE/GZIP; третий аргумент способен изменить формат вопреки имени функции.
Возврат / ошибкиБинарная строка либо false при внутреннем отказе с E_WARNING. Недопустимый level/encoding вызывает ValueError в текущем PHP.
Выборgzip — формат .gz, zlib — оболочка с Adler-32, raw — поток DEFLATE без этой оболочки. Ни один из них сам по себе не является ZIP-архивом нескольких файлов.
Уменьшить повторяющийся отчёт
  1. Строка report содержит повторения
  2. Выбран формат raw DEFLATE
  3. gzdeflate возвращает бинарные байты
  4. gzinflate восстанавливает исходный отчёт
Сжать и восстановить короткий отчётСамостоятельный пример
<?php
declare(strict_types=1);

$report = "order=42;status=ready";
$packed = gzdeflate($report);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
$restored = gzinflate($packed);
var_dump($restored === $report);
echo $restored, "\n";
Ожидаемый результат
bool(true)
order=42;status=ready

Проверяем точные восстановленные данные, а не жёсткий hex сжатого потока: бинарное оформление может зависеть от версии библиотеки, режима и ОС.

Проверить, окупается ли сжатие конкретных данныхСамостоятельный пример
<?php
declare(strict_types=1);

$report = str_repeat("order=42;status=ready\n", 100);
$packed = gzdeflate($report, 6);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
var_dump(strlen($packed) < strlen($report));
var_dump(gzinflate($packed) === $report);
Ожидаемый результат
bool(true)
bool(true)

В этой fixture много повторов, поэтому уменьшение заметно. Для уже сжатого изображения/случайного токена эффект будет другим. Сравнение размера не измеряет время CPU.

Обработать неверные настройкиСамостоятельный пример
<?php
declare(strict_types=1);

try { gzdeflate('report', 10); }
catch (ValueError $error) { echo "Invalid level\n"; }
try { gzdeflate('report', -1, 999); }
catch (ValueError $error) { echo "Invalid format\n"; }
Ожидаемый результат
Invalid level
Invalid format

Это ошибки конфигурации разработчика. Получатель должен знать формат заранее; смена третьего аргумента требует изменить парный декодер.

Байты могут содержать нули и недопустимые UTF-8 последовательности. В БД используйте подходящее бинарное поле; текстовый transport может требовать Base64 с дополнительным увеличением объёма. Не добавляйте к результату произвольный префикс без явного формата конверта. Передача бинарных данных в текстовом API показывает этот слой.

Дальше: gzinflate; zlib_encode.

gzuncompressВосстановить строку из zlib и явно отличить испорченный поток от корректного пустого результата.

PHP 4.0.1+ · zlib

gzuncompress(string $data, int $max_length = 0): string|false

Восстановить строку из zlib и явно отличить испорченный поток от корректного пустого результата.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataБинарные байты формата zlib, обычно результат gzcompress. Имя файла/HTTP-заголовок сами по себе не доказывают, что байты соответствуют формату.
max_lengthЗаявленная максимальная длина распакованных данных; 0 не задаёт пользовательского ограничения. Это не длина читаемого сжатого префикса и не режим «обрезать результат».
Возврат / ошибкиВосстановленная строка, включая пустую, либо false с E_WARNING при повреждении/неподходящем формате/отказе распаковки. Отрицательный max_length даёт ValueError.
Предел гарантийНа PHP 8.5.11/zlib1.3.2 подтверждён выход за точный max_length на границе роста внутреннего буфера. После успешной распаковки дополнительно проверяют strlen; это не предотвращает уже состоявшееся выделение памяти.
ЗащитаИсторическое описание gzinflate/gzuncompress упоминает коэффициент 32768. Не используйте его как бюджет памяти сервиса: ограничивайте вход, выход, время и ресурсы процесса.
Формат и длина проверяются отдельно
  1. Получены байты zlib
  2. gzuncompress пытается восстановить строку
  3. false означает отказ, пустая строка может быть успехом
  4. Приложение проверяет допустимую длину и структуру результата
Получить исходный текст и корректную пустую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$packed = gzcompress('ready');
echo gzuncompress($packed), "\n";
$empty = gzuncompress(gzcompress(''));
var_dump($empty, $empty === false);
Ожидаемый результат
ready
string(0) ""
bool(false)

Обычная проверка if (!$empty) смешала бы пустой успех с false. После распаковки JSON/CSV ещё требует собственного разбора и проверки.

Поймать контролируемую ошибку повреждённых данныхСамостоятельный пример
<?php
declare(strict_types=1);

$warnings = 0;
set_error_handler(function (int $level, string $message) use (&$warnings): bool {
    if ($level !== E_WARNING) { return false; }
    $warnings++;
    return true;
});
try { $decoded = gzuncompress('not a compressed stream'); }
finally { restore_error_handler(); }
var_dump($decoded);
echo $warnings, "\n";
Ожидаемый результат
bool(false)
1

Анонимный обработчик считает ожидаемое E_WARNING этой fixture и возвращает прежний обработчик в finally. В приложении фиксируют причину отказа, не гасят все предупреждения оператором @.

Проверить реальную границу бизнес-лимитаСамостоятельный пример
<?php
declare(strict_types=1);

$limit = 47;
$packed = gzcompress(str_repeat('A', 48));
$decoded = gzuncompress($packed, $limit);
if ($decoded === false || strlen($decoded) > $limit) {
    echo "Payload rejected\n";
} else {
    echo "Payload accepted\n";
}
Ожидаемый результат
Payload rejected

В проверенном PHP8.5.11 декодер здесь возвращает 48 байт при max_length=47. Поэтому последняя проверка обязательна для точного договора. На другой версии декодер может раньше отказать; это также отказ входа. Для жёсткого бюджета памяти нужен ограниченный изолированный процесс/подходящий потоковый API.

Не срезайте «первые 10 и последние 8 байт gzip» ради ручного gzinflate: gzip допускает дополнительные поля заголовка и проверочные данные. Не путайте Content-Encoding (сжатие представления) и HTTP Transfer-Encoding: chunked (передача порциями). Слои должен обработать соответствующий HTTP-клиент.

Дальше: gzcompress; zlib_decode; inflate_init.

gzdecodeВосстановить строку из gzip и явно отличить испорченный поток от корректного пустого результата.

PHP 5.4+ · zlib

gzdecode(string $data, int $max_length = 0): string|false

Восстановить строку из gzip и явно отличить испорченный поток от корректного пустого результата.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataБинарные байты формата gzip, обычно результат gzencode. Имя файла/HTTP-заголовок сами по себе не доказывают, что байты соответствуют формату.
max_lengthЗаявленная максимальная длина распакованных данных; 0 не задаёт пользовательского ограничения. Это не длина читаемого сжатого префикса и не режим «обрезать результат».
Возврат / ошибкиВосстановленная строка, включая пустую, либо false с E_WARNING при повреждении/неподходящем формате/отказе распаковки. Отрицательный max_length даёт ValueError.
Предел гарантийНа PHP 8.5.11/zlib1.3.2 подтверждён выход за точный max_length на границе роста внутреннего буфера. После успешной распаковки дополнительно проверяют strlen; это не предотвращает уже состоявшееся выделение памяти.
ЗащитаИсторическое описание gzinflate/gzuncompress упоминает коэффициент 32768. Не используйте его как бюджет памяти сервиса: ограничивайте вход, выход, время и ресурсы процесса.
Формат и длина проверяются отдельно
  1. Получены байты gzip
  2. gzdecode пытается восстановить строку
  3. false означает отказ, пустая строка может быть успехом
  4. Приложение проверяет допустимую длину и структуру результата
Получить исходный текст и корректную пустую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$packed = gzencode('ready');
echo gzdecode($packed), "\n";
$empty = gzdecode(gzencode(''));
var_dump($empty, $empty === false);
Ожидаемый результат
ready
string(0) ""
bool(false)

Обычная проверка if (!$empty) смешала бы пустой успех с false. После распаковки JSON/CSV ещё требует собственного разбора и проверки.

Поймать контролируемую ошибку повреждённых данныхСамостоятельный пример
<?php
declare(strict_types=1);

$warnings = 0;
set_error_handler(function (int $level, string $message) use (&$warnings): bool {
    if ($level !== E_WARNING) { return false; }
    $warnings++;
    return true;
});
try { $decoded = gzdecode('not a compressed stream'); }
finally { restore_error_handler(); }
var_dump($decoded);
echo $warnings, "\n";
Ожидаемый результат
bool(false)
1

Анонимный обработчик считает ожидаемое E_WARNING этой fixture и возвращает прежний обработчик в finally. В приложении фиксируют причину отказа, не гасят все предупреждения оператором @.

Проверить реальную границу бизнес-лимитаСамостоятельный пример
<?php
declare(strict_types=1);

$limit = 47;
$packed = gzencode(str_repeat('A', 48));
$decoded = gzdecode($packed, $limit);
if ($decoded === false || strlen($decoded) > $limit) {
    echo "Payload rejected\n";
} else {
    echo "Payload accepted\n";
}
Ожидаемый результат
Payload rejected

В проверенном PHP8.5.11 декодер здесь возвращает 48 байт при max_length=47. Поэтому последняя проверка обязательна для точного договора. На другой версии декодер может раньше отказать; это также отказ входа. Для жёсткого бюджета памяти нужен ограниченный изолированный процесс/подходящий потоковый API.

Не срезайте «первые 10 и последние 8 байт gzip» ради ручного gzinflate: gzip допускает дополнительные поля заголовка и проверочные данные. Не путайте Content-Encoding (сжатие представления) и HTTP Transfer-Encoding: chunked (передача порциями). Слои должен обработать соответствующий HTTP-клиент.

Дальше: gzencode; zlib_decode; inflate_init.

gzinflateВосстановить строку из raw DEFLATE и явно отличить испорченный поток от корректного пустого результата.

PHP 4.0.4+ · zlib

gzinflate(string $data, int $max_length = 0): string|false

Восстановить строку из raw DEFLATE и явно отличить испорченный поток от корректного пустого результата.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataБинарные байты формата raw DEFLATE, обычно результат gzdeflate. Имя файла/HTTP-заголовок сами по себе не доказывают, что байты соответствуют формату.
max_lengthЗаявленная максимальная длина распакованных данных; 0 не задаёт пользовательского ограничения. Это не длина читаемого сжатого префикса и не режим «обрезать результат».
Возврат / ошибкиВосстановленная строка, включая пустую, либо false с E_WARNING при повреждении/неподходящем формате/отказе распаковки. Отрицательный max_length даёт ValueError.
Предел гарантийНа PHP 8.5.11/zlib1.3.2 подтверждён выход за точный max_length на границе роста внутреннего буфера. После успешной распаковки дополнительно проверяют strlen; это не предотвращает уже состоявшееся выделение памяти.
ЗащитаИсторическое описание gzinflate/gzuncompress упоминает коэффициент 32768. Не используйте его как бюджет памяти сервиса: ограничивайте вход, выход, время и ресурсы процесса.
Формат и длина проверяются отдельно
  1. Получены байты raw DEFLATE
  2. gzinflate пытается восстановить строку
  3. false означает отказ, пустая строка может быть успехом
  4. Приложение проверяет допустимую длину и структуру результата
Получить исходный текст и корректную пустую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$packed = gzdeflate('ready');
echo gzinflate($packed), "\n";
$empty = gzinflate(gzdeflate(''));
var_dump($empty, $empty === false);
Ожидаемый результат
ready
string(0) ""
bool(false)

Обычная проверка if (!$empty) смешала бы пустой успех с false. После распаковки JSON/CSV ещё требует собственного разбора и проверки.

Поймать контролируемую ошибку повреждённых данныхСамостоятельный пример
<?php
declare(strict_types=1);

$warnings = 0;
set_error_handler(function (int $level, string $message) use (&$warnings): bool {
    if ($level !== E_WARNING) { return false; }
    $warnings++;
    return true;
});
try { $decoded = gzinflate('not a compressed stream'); }
finally { restore_error_handler(); }
var_dump($decoded);
echo $warnings, "\n";
Ожидаемый результат
bool(false)
1

Анонимный обработчик считает ожидаемое E_WARNING этой fixture и возвращает прежний обработчик в finally. В приложении фиксируют причину отказа, не гасят все предупреждения оператором @.

Проверить реальную границу бизнес-лимитаСамостоятельный пример
<?php
declare(strict_types=1);

$limit = 47;
$packed = gzdeflate(str_repeat('A', 48));
$decoded = gzinflate($packed, $limit);
if ($decoded === false || strlen($decoded) > $limit) {
    echo "Payload rejected\n";
} else {
    echo "Payload accepted\n";
}
Ожидаемый результат
Payload rejected

В проверенном PHP8.5.11 декодер здесь возвращает 48 байт при max_length=47. Поэтому последняя проверка обязательна для точного договора. На другой версии декодер может раньше отказать; это также отказ входа. Для жёсткого бюджета памяти нужен ограниченный изолированный процесс/подходящий потоковый API.

Не срезайте «первые 10 и последние 8 байт gzip» ради ручного gzinflate: gzip допускает дополнительные поля заголовка и проверочные данные. Не путайте Content-Encoding (сжатие представления) и HTTP Transfer-Encoding: chunked (передача порциями). Слои должен обработать соответствующий HTTP-клиент.

Дальше: gzdeflate; zlib_decode; inflate_init.

zlib_encodeВыбрать формат сжатия явным аргументом, когда один код обслуживает несколько согласованных форматов обмена.

PHP 5.4+ · zlib

zlib_encode(string $data, int $encoding, int $level = -1): string|false

Выбрать формат сжатия явным аргументом, когда один код обслуживает несколько согласованных форматов обмена.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataИсходная строка байтов.
encodingОбязательная ZLIB_ENCODING_RAW, ZLIB_ENCODING_DEFLATE либо ZLIB_ENCODING_GZIP. Это выбор оболочки над DEFLATE, а не кодировка текста UTF-8/Windows-1251.
level-1..9; здесь третий параметр, тогда как у gzencode/gzcompress/gzdeflate level второй.
Возврат / ошибкиБинарная строка либо false с предупреждением; неверные level/encoding дают ValueError. PHP.net не полностью заполняет описание; договор дополнен tagged PHP8.5.11 source и runtime.
Формат становится явной частью договора
  1. Партнёр ожидает gzip
  2. Передаём ZLIB_ENCODING_GZIP
  3. zlib_encode создаёт соответствующую оболочку
  4. Парный получатель использует gzip-декодер
Явно выбрать gzip для небольшого сообщенияСамостоятельный пример
<?php
declare(strict_types=1);

$packed = zlib_encode('report-ready', ZLIB_ENCODING_GZIP, 6);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
echo gzdecode($packed), "\n";
Ожидаемый результат
report-ready

При таком вызове результат имеет gzip-формат независимо от нейтрального имени функции.

Проверить три согласованных форматаСамостоятельный пример
<?php
declare(strict_types=1);

$formats = [ZLIB_ENCODING_RAW, ZLIB_ENCODING_DEFLATE, ZLIB_ENCODING_GZIP];
foreach ($formats as $format) {
    $packed = zlib_encode('same bytes', $format);
    if ($packed === false) { throw new RuntimeException('Compression failed'); }
    var_dump(zlib_decode($packed) === 'same bytes');
}
Ожидаемый результат
bool(true)
bool(true)
bool(true)

Общий декодер умеет распознавать эти варианты; для строгого endpoint лучше хранить/проверять заранее согласованный формат. ZIP сюда не входит.

Дальше: gzencode; gzcompress; gzdeflate; zlib_decode.

zlib_decodeРаспаковать один из поддерживаемых raw/gzip/zlib форматов в инструменте, где такая вариативность действительно разрешена.

PHP 5.4+ · zlib

zlib_decode(string $data, int $max_length = 0): string|false

Распаковать один из поддерживаемых raw/gzip/zlib форматов в инструменте, где такая вариативность действительно разрешена.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataСжатая строка. PHP пробует zlib/gzip и при data error может перейти к raw DEFLATE. Это не проверка произвольного формата архива.
max_length0 без пользовательского лимита; положительное значение ограничивает декодирование, но в PHP8.5.11 не гарантирует точное совпадение верхней границы буфера. Проверяйте длину результата отдельно.
Возврат / ошибкиСтрока либо false с E_WARNING; отрицательный лимит даёт ValueError. Успешное декодирование не проверяет бизнес-схему данных и не аутентифицирует отправителя.
Импорт поддерживает несколько оболочек
  1. Формат входа из разрешённого набора
  2. zlib_decode распознаёт поддерживаемую оболочку
  3. Получаем исходные байты
  4. Отдельно проверяем длину, JSON/CSV и правила импорта
Прочитать разрешённые варианты импортаСамостоятельный пример
<?php
declare(strict_types=1);

$inputs = [gzencode('gzip'), gzcompress('zlib'), gzdeflate('raw')];
foreach ($inputs as $packed) { echo zlib_decode($packed), "\n"; }
Ожидаемый результат
gzip
zlib
raw

Здесь входные формы созданы в самом примере. Присутствие raw среди разрешённых форматов означает отсутствие встроенной в оболочку контрольной суммы.

Отказаться от неподдерживаемого обычного текстаСамостоятельный пример
<?php
declare(strict_types=1);

$warnings = 0;
set_error_handler(function (int $level, string $message) use (&$warnings): bool {
    if ($level !== E_WARNING) { return false; }
    $warnings++;
    return true;
});
try { $decoded = zlib_decode('plain text'); }
finally { restore_error_handler(); }
var_dump($decoded);
echo $warnings, "\n";
Ожидаемый результат
bool(false)
1

Нет fallback «вернём исходный текст и считаем импорт успешным»: такой режим должен быть отдельно предусмотрен форматом входа.

Проверить свой предел после декодированияСамостоятельный пример
<?php
declare(strict_types=1);

$limit = 47;
$decoded = zlib_decode(gzencode(str_repeat('A', 48)), $limit);
var_dump($decoded === false || strlen($decoded) > $limit);
Ожидаемый результат
bool(true)

Проверяется именно непригодность для лимита, а не обещание конкретного внутреннего буфера. Для нескольких склеенных gzip members используйте явную обработку границ: одно успешное распаковывание не гарантирует потребление всех переданных байтов.

Дальше: zlib_encode; gzdecode; gzuncompress; gzinflate.

deflate_initПодготовить сжатие больших данных порциями, сохраняя историю повторений между частями.

PHP 7+; объект с PHP 8+ · zlib

deflate_init(int $encoding, array|object $options = []): DeflateContext|false

Подготовить сжатие больших данных порциями, сохраняя историю повторений между частями.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
encodingОдин из ZLIB_ENCODING_RAW/DEFLATE/GZIP. Настройка window здесь задаёт размер окна, а не формат, в отличие от некоторых zlib-фильтров.
options.level / memorylevel -1..9, default -1; memory 1..9, default 8. memory — уровень рабочих структур zlib, не лимит памяти PHP в байтах.
options.window / strategywindow 8..15, default 15; strategy одна из ZLIB_FILTERED/HUFFMAN_ONLY/RLE/FIXED/DEFAULT_STRATEGY. При window=8 zlib для zlib-оболочки может поднять окно до 9, raw/gzip могут отказать.
options.dictionaryСтрока либо массив строк заранее согласованного словаря. Нужен тот же договор у декодера. Gzip не поддерживает preset dictionary таким способом; используйте подходящий zlib/raw протокол.
Возврат / ошибкиDeflateContext либо false с предупреждением при ошибке создания. Недопустимые диапазоны/encoding в PHP8.5.11 дают ValueError, вопреки обобщённой старой формулировке «E_WARNING». Неизвестные ключи могут молча игнорироваться.
Граница APIМассив/объект options принимается текущей сигнатурой. Этот API не позволяет произвольно настроить имя/время/comment gzip-заголовка; не обещайте идентичность каждого байта между ОС.
Один контекст на один поток
  1. Создаём context для gzip
  2. Передаём первую часть
  3. Контекст помнит уже встреченные фрагменты
  4. Последнюю часть завершаем FINISH

Контекст хранит состояние сжатия между вызовами: уже увиденную историю и служебные данные алгоритма. Его создаёт init, а add передаёт очередную часть. Часть может дать пустой результат: это не false. Нельзя создавать новый контекст для каждой части и ожидать один непрерывный поток. С PHP 8 контексты — непрозрачные объекты, до PHP 8 были ресурсами.

Размер window задаётся логарифмом по основанию2:15 означает окно истории2^15=32768байт, не15байт и не общий предел памяти. Словарь-массив PHP превращает в последовательность строк с нулевым байтом после каждой: ["order", "status"] соответствует байтам "order\0status\0", а не строке с пробелом. При обмене с другим языком стороны согласуют именно байты. В PHP8.5.11 пустой элемент или NUL внутри элемента такого массива дают ValueError, неподходящий тип dictionary — TypeError. Переданная напрямую строка словаря может содержать NUL.

Создать контекст и получить маленький gzipСамостоятельный пример
<?php
declare(strict_types=1);

$context = deflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$packed = deflate_add($context, 'report', ZLIB_FINISH);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
echo gzdecode($packed), "\n";
var_dump($context instanceof DeflateContext);
Ожидаемый результат
report
bool(true)

instanceof проверяет тип непрозрачного объекта. Пользователь не заполняет его поля вручную: состояние управляется функциями zlib.

Поймать ошибки размера окна и уровняСамостоятельный пример
<?php
declare(strict_types=1);

try { deflate_init(ZLIB_ENCODING_GZIP, ['level' => 10]); }
catch (ValueError $error) { echo "Bad level\n"; }
try { deflate_init(ZLIB_ENCODING_GZIP, ['window' => 7]); }
catch (ValueError $error) { echo "Bad window\n"; }
Ожидаемый результат
Bad level
Bad window

Это валидация конфигурации. Опечатка в имени ключа может не вызвать ошибку: приложение должно формировать разрешённый набор параметров.

Согласовать словарь для однотипных сообщенийСамостоятельный пример
<?php
declare(strict_types=1);

$dictionary = 'order status customer delivery';
$encoder = deflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => $dictionary]);
$decoder = inflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => $dictionary]);
if ($encoder === false || $decoder === false) { throw new RuntimeException('Context unavailable'); }
$packed = deflate_add($encoder, 'order status ready', ZLIB_FINISH);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
echo inflate_add($decoder, $packed, ZLIB_FINISH), "\n";
Ожидаемый результат
order status ready

Словарь помогает протоколу с повторяемыми короткими сообщениями, только если обе стороны знают одинаковые байты. Это не пароль и не шифрование; при смене словаря нужна версия формата.

Согласовать массив словаря с его точными байтамиСамостоятельный пример
<?php
declare(strict_types=1);

$encoder = deflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => ['order', 'status']]);
$decoder = inflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => "order\0status\0"]);
if ($encoder === false || $decoder === false) { throw new RuntimeException('Context unavailable'); }
$packed = deflate_add($encoder, 'order status', ZLIB_FINISH);
if ($packed === false) { throw new RuntimeException('Compression failed'); }
echo inflate_add($decoder, $packed, ZLIB_FINISH), "\n";
var_dump(inflate_get_status($decoder) === ZLIB_STREAM_END);
Ожидаемый результат
order status
bool(true)

Компрессор получил массив, декомпрессор — эквивалентную строку с двумя нулевыми байтами. Подстановка пробелов дала бы другой словарь и отказ.

Дальше: deflate_add; inflate_init.

deflate_addДобавить очередные данные в контекст и получить созданную на этом шаге сжатую часть.

PHP 7+; объект с PHP 8+ · zlib

deflate_add(DeflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false

Добавить очередные данные в контекст и получить созданную на этом шаге сжатую часть.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
contextРезультат deflate_init; с PHP8 объект, ранее ресурс. Один context связан с состоянием конкретного потока.
dataОчередная исходная строка. Это не вся предыдущая строка заново: повторная подача повторно добавит данные.
flush_modeNO_FLUSH/PARTIAL_FLUSH/SYNC_FLUSH/FULL_FLUSH/BLOCK/FINISH; неверный режим даёт ValueError в текущем PHP.
ВозвратСжатая часть, возможно пустая строка, либо false с предупреждением. Все успешные части передают получателю в исходном порядке.
ЗавершениеFINISH завершает поток. PHP8.5.11 после успешного окончания сбрасывает deflate-контекст; следующий FINISH может начать новый отдельный поток. Это не продолжение старого содержимого.
Склеиваются результаты add, а не исходные повторы
  1. Часть A → add(NO_FLUSH)
  2. Часть B → add(NO_FLUSH)
  3. Конец → add(FINISH)
  4. Бинарные результаты всех шагов образуют один поток

Контекст хранит состояние сжатия между вызовами: уже увиденную историю и служебные данные алгоритма. Его создаёт init, а add передаёт очередную часть. Часть может дать пустой результат: это не false. Нельзя создавать новый контекст для каждой части и ожидать один непрерывный поток. С PHP 8 контексты — непрозрачные объекты, до PHP 8 были ресурсами.

Размер window задаётся логарифмом по основанию2:15 означает окно истории2^15=32768байт, не15байт и не общий предел памяти. Словарь-массив PHP превращает в последовательность строк с нулевым байтом после каждой: ["order", "status"] соответствует байтам "order\0status\0", а не строке с пробелом. При обмене с другим языком стороны согласуют именно байты. В PHP8.5.11 пустой элемент или NUL внутри элемента такого массива дают ValueError, неподходящий тип dictionary — TypeError. Переданная напрямую строка словаря может содержать NUL.

РежимЧто означает
ZLIB_NO_FLUSHНе требовать немедленного завершения порции; сохраняет больше возможностей для сжатия.
ZLIB_SYNC_FLUSHВыдать накопленное так, чтобы декодер мог получить доступные данные; поток ещё продолжается. Режим add по умолчанию.
ZLIB_PARTIAL_FLUSHИсторический частичный flush; в новом обычном сценарии выбирают более понятный SYNC_FLUSH.
ZLIB_FULL_FLUSHСбросить историю сжатия для возможного начала декодирования с контрольной точки; ухудшает степень сжатия.
ZLIB_BLOCKЗакончить текущий блок/обработать до границы блока. Специализированное управление, не граница бизнес-сообщения.
ZLIB_FINISHСообщить, что подаётся последний фрагмент потока. У распаковки дополнительно проверяют ZLIB_STREAM_END.
Сжать отчёт из нескольких строкСамостоятельный пример
<?php
declare(strict_types=1);

$context = deflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$packed = '';
foreach (["one\n", "two\n"] as $part) {
    $chunk = deflate_add($context, $part, ZLIB_NO_FLUSH);
    if ($chunk === false) { throw new RuntimeException('Compression failed'); }
    $packed .= $chunk;
}
$last = deflate_add($context, '', ZLIB_FINISH);
if ($last === false) { throw new RuntimeException('Finish failed'); }
$packed .= $last;
echo gzdecode($packed);
Ожидаемый результат
one
two

В учебном примере всё собирается в packed ради проверки. Для большого экспорта успешные бинарные chunks записывают в выходной поток с проверкой коротких записей, чтобы не держать весь архив в памяти.

Не считать пустую часть ошибкойСамостоятельный пример
<?php
declare(strict_types=1);

$context = deflate_init(ZLIB_ENCODING_RAW);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$chunk = deflate_add($context, '', ZLIB_NO_FLUSH);
var_dump($chunk, $chunk === false);
$last = deflate_add($context, '', ZLIB_FINISH);
var_dump(is_string($last), gzinflate($last) === '');
Ожидаемый результат
string(0) ""
bool(false)
bool(true)
bool(true)

Пустой вход без FINISH ничего не выдаёт. FINISH даже для пустого сообщения формирует корректный завершённый поток.

Увидеть границу двух законченных потоковСамостоятельный пример
<?php
declare(strict_types=1);

$context = deflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$first = deflate_add($context, 'first', ZLIB_FINISH);
$second = deflate_add($context, 'second', ZLIB_FINISH);
echo gzdecode($first), "\n", gzdecode($second), "\n";
Ожидаемый результат
first
second

Это проверенное поведение PHP8.5.11. Для ясной архитектуры независимым документам можно создавать отдельные контексты; получатель двух склеенных members должен явно поддерживать такой контейнер.

Дальше: deflate_init; inflate_add.

inflate_initСоздать состояние для постепенной распаковки согласованного сжатого потока.

PHP 7+; объект с PHP 8+ · zlib

inflate_init(int $encoding, array|object $options = []): InflateContext|false

Создать состояние для постепенной распаковки согласованного сжатого потока.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
encodingZLIB_ENCODING_RAW/DEFLATE/GZIP по договору. Это не автоматическое распознавание zlib_decode.
Действующие optionsВ PHP8.5.11 реализация читает window 8..15 (default15) и dictionary. Массив/объект параметров должен содержать согласованные значения.
Расхождение документацииPHP.net перечисляет также level,memory,strategy по аналогии со сжатием. В tagged PHP8.5.11 inflate_init их не применяет: они не настраивают скорость/память декодера. Неизвестные ключи также не проверяются как схема.
dictionaryТе же байты preset dictionary, что у компрессора, если формат его требует. Отсутствие/несовпадение обнаружится при распаковке.
Возврат / ошибкиInflateContext с PHP8, ранее ресурс; false с E_WARNING при внутреннем отказе. Неверные encoding/window вызывают ValueError в текущем PHP.
ЛимитыАвтоматического предела размера распакованного результата как параметра max_length здесь нет. Даже один маленький chunk способен породить большой выход.
Распаковщик помнит незавершённый поток
  1. Выбираем gzip
  2. inflate_init создаёт контекст
  3. Передаём поступающие байты в inflate_add
  4. Проверяем конец потока и общий размер результата

Контекст хранит состояние сжатия между вызовами: уже увиденную историю и служебные данные алгоритма. Его создаёт init, а add передаёт очередную часть. Часть может дать пустой результат: это не false. Нельзя создавать новый контекст для каждой части и ожидать один непрерывный поток. С PHP 8 контексты — непрозрачные объекты, до PHP 8 были ресурсами.

Размер window задаётся логарифмом по основанию2:15 означает окно истории2^15=32768байт, не15байт и не общий предел памяти. Словарь-массив PHP превращает в последовательность строк с нулевым байтом после каждой: ["order", "status"] соответствует байтам "order\0status\0", а не строке с пробелом. При обмене с другим языком стороны согласуют именно байты. В PHP8.5.11 пустой элемент или NUL внутри элемента такого массива дают ValueError, неподходящий тип dictionary — TypeError. Переданная напрямую строка словаря может содержать NUL.

Распаковать известный формат через контекстСамостоятельный пример
<?php
declare(strict_types=1);

$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$decoded = inflate_add($context, gzencode('catalog'), ZLIB_FINISH);
echo $decoded, "\n";
var_dump(inflate_get_status($context) === ZLIB_STREAM_END);
Ожидаемый результат
catalog
bool(true)

FINISH сам по себе не сертификат завершённости входа: проверка статуса подтверждает достигнутый конец потока.

Проверить ошибку активной настройкиСамостоятельный пример
<?php
declare(strict_types=1);

try { inflate_init(ZLIB_ENCODING_GZIP, ['window' => 16]); }
catch (ValueError $error) { echo "Bad window\n"; }
$context = inflate_init(ZLIB_ENCODING_GZIP, ['level' => 999]);
var_dump($context instanceof InflateContext);
Ожидаемый результат
Bad window
bool(true)

Второй вызов намеренно демонстрирует игнорируемый level в PHP8.5.11. Это не рекомендация передавать 999: рабочий код вообще не включает неиспользуемые настройки.

Получить явный отказ без необходимого словаряСамостоятельный пример
<?php
declare(strict_types=1);

$encoder = deflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => 'order status customer']);
if ($encoder === false) { throw new RuntimeException('Encoder unavailable'); }
$packed = deflate_add($encoder, 'order status ready', ZLIB_FINISH);
$decoder = inflate_init(ZLIB_ENCODING_DEFLATE);
if ($decoder === false) { throw new RuntimeException('Decoder unavailable'); }
$warnings = 0;
set_error_handler(function (int $level, string $message) use (&$warnings): bool {
    if ($level !== E_WARNING) { return false; }
    $warnings++;
    return true;
});
try { $decoded = inflate_add($decoder, $packed, ZLIB_FINISH); }
finally { restore_error_handler(); }
var_dump($decoded, inflate_get_status($decoder) === ZLIB_NEED_DICT);
echo $warnings, "\n";
Ожидаемый результат
bool(false)
bool(true)
1

Обработчик считает ожидаемое предупреждение этой fixture. Правильный путь — передать согласованный dictionary при создании нового декодера; угадывание словаря не часть обычного импорта.

Отличить неверный вид словаря от отсутствующего словаряСамостоятельный пример
<?php
declare(strict_types=1);

foreach ([[''], ["bad\0entry"]] as $dictionary) {
    try { inflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => $dictionary]); }
    catch (ValueError $error) { echo "bad element\n"; }
}
try { inflate_init(ZLIB_ENCODING_DEFLATE, ['dictionary' => new stdClass()]); }
catch (TypeError $error) { echo "bad type\n"; }
Ожидаемый результат
bad element
bad element
bad type

Ошибку структуры конфигурации выявляют при init. Это отличается от корректно созданного декодера, которому затем не подошли байты словаря полученного потока.

Дальше: inflate_add; deflate_init; inflate_get_status.

inflate_addПередать очередные сжатые байты декодеру и получить доступную распакованную часть.

PHP 7+; объект с PHP 8+ · zlib

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

Передать очередные сжатые байты декодеру и получить доступную распакованную часть.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
context / dataКонтекст inflate_init и только новые сжатые байты. Не передавайте повторно уже потреблённый префикс.
flush_modeОдин из шести режимов. Для поточного ввода важны NO_FLUSH/SYNC_FLUSH и FINISH на последнем входе; это управление декодером, а не «уровень сжатия».
Возврат / ошибкиРаспакованная часть, включая пустую строку, либо false с E_WARNING при повреждении/неверной сумме/словаре. Неверный flush_mode даёт ValueError.
ПолнотаДаже после FINISH строка может быть частичным результатом незавершённого входа. Требуйте inflate_get_status(context) === ZLIB_STREAM_END.
Служебные данныеGzip-имя файла, комментарий и прочие поля заголовка этот API не возвращает. После конца следующий вызов в PHP8.5.11 лениво сбрасывает состояние.
Из фрагментов сети в проверенный документ
  1. Получили первый бинарный chunk
  2. inflate_add вернул доступный текст или пустую строку
  3. Последняя часть обработана с FINISH
  4. Приложение проверило STREAM_END, размер и остаток входа

Контекст хранит состояние сжатия между вызовами: уже увиденную историю и служебные данные алгоритма. Его создаёт init, а add передаёт очередную часть. Часть может дать пустой результат: это не false. Нельзя создавать новый контекст для каждой части и ожидать один непрерывный поток. С PHP 8 контексты — непрозрачные объекты, до PHP 8 были ресурсами.

Размер window задаётся логарифмом по основанию2:15 означает окно истории2^15=32768байт, не15байт и не общий предел памяти. Словарь-массив PHP превращает в последовательность строк с нулевым байтом после каждой: ["order", "status"] соответствует байтам "order\0status\0", а не строке с пробелом. При обмене с другим языком стороны согласуют именно байты. В PHP8.5.11 пустой элемент или NUL внутри элемента такого массива дают ValueError, неподходящий тип dictionary — TypeError. Переданная напрямую строка словаря может содержать NUL.

Распаковать документ из маленьких бинарных частейСамостоятельный пример
<?php
declare(strict_types=1);

$packed = gzencode("one\ntwo\n");
$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$decoded = '';
foreach (str_split($packed, 5) as $part) {
    $chunk = inflate_add($context, $part, ZLIB_SYNC_FLUSH);
    if ($chunk === false) { throw new RuntimeException('Bad compressed data'); }
    $decoded .= $chunk;
    if (strlen($decoded) > 1000) { throw new RuntimeException('Output limit'); }
}
if (inflate_get_status($context) !== ZLIB_STREAM_END) { throw new RuntimeException('Incomplete stream'); }
echo $decoded;
Ожидаемый результат
one
two

Здесь str_split делит fixture, а не читает сеть. При настоящем импорте выдаваемые chunks передают дальше, считая общий объём. Проверка после вызова не ограничивает пиковое выделение памяти внутри этого вызова.

Не принять частичный результат за готовый документСамостоятельный пример
<?php
declare(strict_types=1);

$packed = substr(gzencode('order-ready'), 0, -4);
$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$decoded = inflate_add($context, $packed, ZLIB_FINISH);
var_dump(is_string($decoded));
var_dump(inflate_get_status($context) === ZLIB_STREAM_END);
Ожидаемый результат
bool(true)
bool(false)

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

Для недоверенного большого архива ограничивают размер входа, суммарный выход, время и память изолированного обработчика. Разбиение на chunks не является само по себе защитой от decompression bomb. Сетевое отсутствие очередных байтов тоже не означает корректного завершения потока.

Дальше: inflate_init; inflate_get_status; inflate_get_read_len.

inflate_get_statusУзнать состояние распаковки и подтвердить именно конец корректного сжатого потока.

PHP 7.2+; объект с PHP 8+ · zlib

inflate_get_status(InflateContext $context): int

Узнать состояние распаковки и подтвердить именно конец корректного сжатого потока.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
contextКонтекст inflate_init; сам вызов статуса не распаковывает данные.
ВозвратЦелочисленный код, обычно ZLIB_OK или ZLIB_STREAM_END, возможны NEED_DICT/BUF_ERROR/DATA_ERROR и другие состояния библиотеки.
ГраницаOK означает отсутствие специального завершения, а не «весь документ получен». BUF_ERROR может означать нехватку следующей порции/невозможность продвижения, не обязательно повреждение.
Проверяется состояние, а не правдоподобие текста
  1. Декодер вернул строку
  2. Читаем status
  3. STREAM_END подтверждает конец потока
  4. Другой статус требует ещё ввода или отказа по условиям
Сравнить начальное и завершённое состояниеСамостоятельный пример
<?php
declare(strict_types=1);

$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
var_dump(inflate_get_status($context) === ZLIB_OK);
inflate_add($context, gzencode('ready'), ZLIB_FINISH);
var_dump(inflate_get_status($context) === ZLIB_STREAM_END);
Ожидаемый результат
bool(true)
bool(true)

Начальное OK не означает, что вообще поступили какие-то данные. Конец получен после полного gzip.

Остановить обработку обрезанного потокаСамостоятельный пример
<?php
declare(strict_types=1);

$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
$packed = substr(gzencode('ready'), 0, 8);
inflate_add($context, $packed, ZLIB_FINISH);
echo inflate_get_status($context) === ZLIB_STREAM_END ? "Complete\n" : "Incomplete\n";
Ожидаемый результат
Incomplete

Это короткий неполный заголовок. Не нужно угадывать конкретный status для каждого разреза входа, если ваша обязательная постусловие — достигнутый конец.

Дальше: inflate_add; inflate_get_read_len.

inflate_get_read_lenУзнать, сколько сжатых входных байтов реально потребил декодер, и обнаружить хвост после первого потока.

PHP 7.2+; объект с PHP 8+ · zlib

inflate_get_read_len(InflateContext $context): int

Узнать, сколько сжатых входных байтов реально потребил декодер, и обнаружить хвост после первого потока.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
contextРезультат inflate_init.
ВозвратЧисло потреблённых сжатых байтов текущего zlib-потока, не число выданных символов и не размер распакованной строки. Текущая сигнатура int; старый текст PHP.net с false не соответствует PHP8.5.11.
СбросПосле STREAM_END счётчик доступен до следующего inflate_add. Следующий вызов лениво сбросит контекст и счётчик; сохраняйте значение до него.
ПрименениеПроверить отсутствие лишнего хвоста либо последовательно обработать разрешённые gzip members. Формат приложения решает, допустимы ли несколько members.
Проверить именно потреблённый префикс
  1. В буфере gzip(one) + gzip(two)
  2. Один inflate_add заканчивает первый member
  3. read_len показывает длину первого префикса
  4. Хвост нужно отклонить или обработать явно
Сравнить потреблённый ввод с полным потокомСамостоятельный пример
<?php
declare(strict_types=1);

$packed = gzencode('ready');
$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
inflate_add($context, $packed, ZLIB_FINISH);
var_dump(inflate_get_read_len($context) === strlen($packed));
Ожидаемый результат
bool(true)

Не сравниваем значение с длиной слова ready: счётчик учитывает сжатую оболочку, а не только полезный текст.

Обработать два явно разрешённых gzip memberСамостоятельный пример
<?php
declare(strict_types=1);

$first = gzencode('one');
$second = gzencode('two');
$buffer = $first . $second;
$context = inflate_init(ZLIB_ENCODING_GZIP);
if ($context === false) { throw new RuntimeException('Context unavailable'); }
echo inflate_add($context, $buffer, ZLIB_FINISH), "\n";
if (inflate_get_status($context) !== ZLIB_STREAM_END) { throw new RuntimeException('First member incomplete'); }
$consumed = inflate_get_read_len($context);
var_dump($consumed === strlen($first));
$tail = substr($buffer, $consumed);
echo inflate_add($context, $tail, ZLIB_FINISH), "\n";
var_dump(inflate_get_status($context) === ZLIB_STREAM_END);
Ожидаемый результат
one
bool(true)
two
bool(true)

Для общего цикла проверяют, что consumed продвигается, ограничивают количество members и суммарный выход. Здесь ровно два известных member. Один gzdecode от склеенного buffer не стоит считать проверкой обоих.

Дальше: inflate_get_status; inflate_add.

gzopenОткрыть gzip-файл для чтения или записи, не собирая весь распакованный документ в памяти.

PHP 4+ · zlib

gzopen(string $filename, string $mode, bool $use_include_path = false): resource|false

Открыть gzip-файл для чтения или записи, не собирая весь распакованный документ в памяти.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
filenameПуть к файлу; отсутствие/недоступность при чтении вызывает E_WARNING и false. Прозрачное чтение обычного несжатого файла допустимо: успех не доказывает gzip-формат.
moderb — чтение; wb — запись с обнулением; ab — добавление. Не поддерживается чтение и запись одним режимом через +. К режиму записи можно добавить уровень0..9 и f (filtered) либо h (Huffman only), например wb9.
use_include_pathfalse по умолчанию; true разрешает поиск через include_path. С PHP8.5 тип bool вместо прежнего int. Для конкретной выгрузки обычно нужен явный путь.
ВозвратРесурс потока либо false. Ресурс закрывают gzclose в finally. Режим и уровень меняют CPU/степень сжатия, не смысл исходных данных.
Открыть → обработать → закрыть
  1. report.gz на диске
  2. gzopen rb → ресурс
  3. gzread отдаёт A1
  4. gzclose освобождает поток

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Прочитать первые два байта выгрузкиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    echo gzread($stream, 2), "
";
} finally { gzclose($stream); }
Ожидаемый результат
A1

Создание fixture через gzencode нужно только для самостоятельного запуска. В проекте report.gz, например, уже получен от поставщика.

Сохранить отчёт с выбранным уровнемСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/export.gz';
$stream = gzopen($path, 'wb6');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    $text = "order=25\n";
    if (gzwrite($stream, $text) !== strlen($text)) { throw new RuntimeException('Write failed'); }
} finally { gzclose($stream); }
echo gzdecode(file_get_contents($path));
Ожидаемый результат
order=25

Файл wb обнуляется при открытии. Для замены важной выгрузки пишут во временный файл и выполняют согласованную публикацию, не портят старый файл до готовности нового.

Не путать прозрачное чтение с проверкой форматаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/plain.txt';
file_put_contents($path, 'not compressed');
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try { echo gzread($stream, 100), "\n"; }
finally { gzclose($stream); }
Ожидаемый результат
not compressed

gzopen читает и обычный файл. Если вход обязан быть завершённым gzip-потоком, нужен отдельный договор и проверка декодером, а не только расширение .gz.

Дальше: gzclose; gzread; gzwrite; gzfile.

gzcloseЗакрыть gz-поток, завершить запись и освободить связанный файловый ресурс.

PHP 4+ · zlib

gzclose(resource $stream): bool

Закрыть gz-поток, завершить запись и освободить связанный файловый ресурс.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
Возвратtrue при успешном закрытии; false при отказе. При записи ошибки могут проявиться поздно, поэтому проверяют и gzwrite, и gzclose.
Завершение ресурса
  1. Записаны исходные байты
  2. gzclose завершает поток
  3. Ресурс больше не пригоден
  4. Получатель читает файл

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Увидеть закрытие ресурсаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
var_dump(is_resource($stream));
var_dump(gzclose($stream));
var_dump(is_resource($stream));
Ожидаемый результат
bool(true)
bool(true)
bool(false)

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

Проверить завершение записанного файлаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/status.gz';
$stream = gzopen($path, 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
$written = false;
try { $written = gzwrite($stream, 'READY'); }
finally { $closed = gzclose($stream); }
if ($written !== 5 || !$closed) { throw new RuntimeException('Export failed'); }
echo gzdecode(file_get_contents($path)), "\n";
Ожидаемый результат
READY

Успешное закрытие не заменяет fsync, транзакцию публикации и проверку целостности у получателя. Ошибку записи не скрывают успешным close.

Дальше: gzopen; gzwrite.

gzwriteЗаписать исходные байты в gz-поток, получив число принятых байтов.

PHP 4+ · zlib

gzwrite(resource $stream, string $data, ?int $length = null): int|false

Записать исходные байты в gz-поток, получив число принятых байтов.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
dataОбычная исходная строка; поток сжимает её сам. Повторный gzencode перед записью обычно создаёт ненужное двойное сжатие.
lengthnull — вся строка; положительное значение ограничивает число исходных байтов. С PHP8 параметр nullable.
ВозвратЧисло записанных несжатых байтов либо false. До PHP7.4 ошибка возвращала0. Проверяйте также короткую запись и0, а не только false.
Псевдонимgzputs — другое имя gzwrite, контракт и реализация одинаковые.
Обычный текст на входе, gzip на диске
  1. Передать строку READY
  2. Поток сжимает данные
  3. Получить5 — исходные байты
  4. gzclose завершает файл

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Записать короткую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/ready.gz';
$stream = gzopen($path, 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try { var_dump(gzwrite($stream, 'READY')); }
finally { gzclose($stream); }
echo gzdecode(file_get_contents($path)), "
";
Ожидаемый результат
int(5)
READY

Число5 относится к READY. Размер полученного gzip-файла иной; маленькая строка из-за служебных полей может даже увеличиться.

Ограничить запись тремя исходными байтамиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/part.gz';
$stream = gzopen($path, 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try { var_dump(gzwrite($stream, 'ABCDEF', 3)); }
finally { gzclose($stream); }
echo gzdecode(file_get_contents($path)), "
";
Ожидаемый результат
int(3)
ABC

length считает байты, не символы Unicode; обрезанный посередине русский символ уже не будет корректным UTF-8.

Продолжать короткую запись с нужного смещенияСамостоятельный пример
<?php
declare(strict_types=1);

$stream = gzopen(__DIR__ . '/rows.gz', 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
$data = "A1
B2
";
try {
    $offset = 0;
    while ($offset < strlen($data)) {
        $count = gzwrite($stream, substr($data, $offset));
        if ($count === false || $count === 0) { throw new RuntimeException('No progress'); }
        $offset += $count;
    }
    echo $offset, "
";
} finally { gzclose($stream); }
Ожидаемый результат
6

В демонстрации маленький буфер, поэтому копия substr допустима. Для больших экспортов формируют ограниченные куски, контролируют время/ошибки и проверяют закрытие. Повторять весь data после короткой записи нельзя: получится дубликат.

Дальше: gzopen; gzclose; gzread.

gzputsЗаписать исходные байты в gz-поток через псевдоним gzwrite.

PHP 4+ · zlib

gzputs(resource $stream, string $data, ?int $length = null): int|false

Записать исходные байты в gz-поток через псевдоним gzwrite.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
dataОбычная исходная строка; поток сжимает её сам. Повторный gzencode перед записью обычно создаёт ненужное двойное сжатие.
lengthnull — вся строка; положительное значение ограничивает число исходных байтов. С PHP8 параметр nullable.
ВозвратЧисло записанных несжатых байтов либо false. До PHP7.4 ошибка возвращала0. Проверяйте также короткую запись и0, а не только false.
Псевдонимgzputs — другое имя gzwrite, контракт и реализация одинаковые.
Обычный текст на входе, gzip на диске
  1. Передать строку READY
  2. Поток сжимает данные
  3. Получить5 — исходные байты
  4. gzclose завершает файл

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Записать короткую строкуСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/ready.gz';
$stream = gzopen($path, 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try { var_dump(gzputs($stream, 'READY')); }
finally { gzclose($stream); }
echo gzdecode(file_get_contents($path)), "
";
Ожидаемый результат
int(5)
READY

Число5 относится к READY. Размер полученного gzip-файла иной; маленькая строка из-за служебных полей может даже увеличиться.

Ограничить запись тремя исходными байтамиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/part.gz';
$stream = gzopen($path, 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try { var_dump(gzputs($stream, 'ABCDEF', 3)); }
finally { gzclose($stream); }
echo gzdecode(file_get_contents($path)), "
";
Ожидаемый результат
int(3)
ABC

length считает байты, не символы Unicode; обрезанный посередине русский символ уже не будет корректным UTF-8.

Продолжать короткую запись с нужного смещенияСамостоятельный пример
<?php
declare(strict_types=1);

$stream = gzopen(__DIR__ . '/rows.gz', 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
$data = "A1
B2
";
try {
    $offset = 0;
    while ($offset < strlen($data)) {
        $count = gzputs($stream, substr($data, $offset));
        if ($count === false || $count === 0) { throw new RuntimeException('No progress'); }
        $offset += $count;
    }
    echo $offset, "
";
} finally { gzclose($stream); }
Ожидаемый результат
6

В демонстрации маленький буфер, поэтому копия substr допустима. Для больших экспортов формируют ограниченные куски, контролируют время/ошибки и проверяют закрытие. Повторять весь data после короткой записи нельзя: получится дубликат.

Дальше: gzopen; gzclose; gzread.

gzreadПрочитать до заданного числа распакованных байтов с текущей позиции.

PHP 4+ · zlib

gzread(resource $stream, int $length): string|false

Прочитать до заданного числа распакованных байтов с текущей позиции.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
lengthПоложительное максимальное число распакованных байтов. Чтение заканчивается раньше на EOF; число0/отрицательное в текущем PHP даёт ValueError.
ВозвратСтрока, включая пустую строку на конце, либо false при отказе. До PHP7.4 ошибка возвращала0. Короткая строка не обязана означать ошибку.
Читать небольшими порциями
  1. report.gz
  2. gzread 2 → A1
  3. Следующий вызов продолжает после A1
  4. Пустая строка и EOF → конец

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Два чтения продолжают друг другаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    echo gzread($stream, 2), "|", gzread($stream, 4);
} finally { gzclose($stream); }
Ожидаемый результат
A1|
B2

Второй вызов получает оставшиеся четыре байта, включая переводы строк.

Читать крупную выгрузку ограниченными порциямиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    $total = 0;
    while (!gzeof($stream)) {
        $part = gzread($stream, 2);
        if ($part === false) { throw new RuntimeException('Read failed'); }
        if ($part === '' && !gzeof($stream)) { throw new RuntimeException('No progress'); }
        $total += strlen($part);
        if ($total > 1024) { throw new RuntimeException('Export too large'); }
        echo $part;
    }
    echo 'bytes=', $total, "
";
} finally { gzclose($stream); }
Ожидаемый результат
A1
B2
bytes=6

Лимит проверяется до дальнейшей обработки очередной порции. Сам gzip-файл и время распаковки также ограничивают; декодер может использовать внутреннюю память. Для недоверенного файла проверяют завершённость формата отдельно.

Дальше: gzgets; gzeof; gzfile; inflate_add.

gzgetsПолучить строку текста из gzip-выгрузки, сохранив её перевод строки.

PHP 4+ · zlib

gzgets(resource $stream, ?int $length = null): string|false

Получить строку текста из gzip-выгрузки, сохранив её перевод строки.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
lengthДо length−1 распакованных байтов, либо до , либо EOF. null снимает этот предел; с PHP8 параметр nullable, раньше default1024. Без предела одна гигантская строка способна занять много памяти.
ВозвратСтрока либо false при ошибке/отсутствии следующей строки. Последняя строка может не иметь . Часть длинной строки ещё не является целой записью.
Построчный журнал
  1. Первый вызов → A1 и перевод строки
  2. Второй → B2 и перевод строки
  3. Третий → false
  4. EOF подтверждает конец

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Прочитать две строкиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    echo gzgets($stream);
    echo gzgets($stream);
    var_dump(gzgets($stream));
} finally { gzclose($stream); }
Ожидаемый результат
A1
B2
bool(false)

false на EOF отличается от успешной строки "0". Проверяйте строгое сравнение.

Увидеть, почему часть строки не равна записиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    echo json_encode(gzgets($stream, 2)), "
";
    echo json_encode(gzgets($stream)), "
";
} finally { gzclose($stream); }
Ожидаемый результат
"A"
"1\n"

length2 разрешил только один байт. При разборе NDJSON/CSV нельзя отправлять такой кусок в парсер как готовую строку; собирайте запись до разделителя с собственным пределом размера.

Перебрать строки и проверить окончаниеСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    $count = 0;
    while (($line = gzgets($stream, 128)) !== false) {
        $count++;
        echo $count, ':', rtrim($line, "

"), "
";
    }
    if (!gzeof($stream)) { throw new RuntimeException('Read failed'); }
} finally { gzclose($stream); }
Ожидаемый результат
1:A1
2:B2

Здесь fixture гарантирует строки короче127байт. В реальной загрузке длинную строку нужно явно отклонять или собирать; gzeof само по себе не доказывает целостность gzip.

Дальше: gzread; gzgetc; gzeof.

gzgetcПрочитать один распакованный байт; удобно разбирать простой ASCII-разделитель.

PHP 4+ · zlib

gzgetc(resource $stream): string|false

Прочитать один распакованный байт; удобно разбирать простой ASCII-разделитель.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
ВозвратОднобайтная строка либо false при EOF/ошибке. «Character» здесь не означает полноценный символ Unicode.
Один шаг — один байт
  1. В потоке A1
  2. Первый gzgetc → A
  3. Второй → 1
  4. Каждый вызов сдвигает позицию

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Прочитать два байтаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try { echo gzgetc($stream), '|', gzgetc($stream), "
"; }
finally { gzclose($stream); }
Ожидаемый результат
A|1

Для обычного чтения больших файлов вызов на каждый байт неоправданно дорог: используйте gzread.

Увидеть два байта одного русского символаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/letter.gz';
file_put_contents($path, gzencode('Я'));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    echo bin2hex(gzgetc($stream)), "\n";
    echo bin2hex(gzgetc($stream)), "\n";
    var_dump(gzgetc($stream));
} finally { gzclose($stream); }
Ожидаемый результат
d0
af
bool(false)

Я в UTF-8 состоит из D0 AF. Для обработки символов сначала соберите корректную текстовую строку и выберите mbstring или другой подходящий Unicode-инструмент.

Дальше: gzread; gzgets.

gzeofУзнать, достиг ли gz-поток конца либо состояния ошибки.

PHP 4+ · zlib

gzeof(resource $stream): bool

Узнать, достиг ли gz-поток конца либо состояния ошибки.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
Возвратtrue при EOF или ошибке, false иначе, включая socket timeout в общем потоковом контракте. Это не контрольная сумма и не свидетельство успешной загрузки.
Проверяется состояние потока
  1. Поток открыт
  2. Читаем данные
  3. Пробуем читать после конца
  4. gzeof сообщает конец

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Проверить состояние до и после чтенияСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    var_dump(gzeof($stream));
    gzread($stream, 100);
    gzread($stream, 1);
    var_dump(gzeof($stream));
} finally { gzclose($stream); }
Ожидаемый результат
bool(false)
bool(true)

Отдельное чтение после конца делает демонстрацию очевидной; момент установки EOF у разных потоков не одинаков.

Не потерять строку с нулёмСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/zero.gz';
file_put_contents($path, gzencode('0'));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    while (!gzeof($stream)) {
        $part = gzread($stream, 32);
        if ($part === false) { throw new RuntimeException('Read failed'); }
        if ($part === '') { break; }
        echo $part, "\n";
    }
} finally { gzclose($stream); }
Ожидаемый результат
0

Условие if (!$part) ошибочно приняло бы строку0 за ложь. При более общих потоках пустое чтение без EOF требует отдельной стратегии ожидания/ошибки.

Дальше: gzread; gzgets; inflate_get_status.

gzfileЗагрузить весь распакованный текст gzip-файла в массив строк.

PHP 4+ · zlib

gzfile(string $filename, bool $use_include_path = false): array|false

Загрузить весь распакованный текст gzip-файла в массив строк.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
filenameПуть к файлу. Как другие gz-файловые функции может прозрачно читать несжатый файл.
use_include_pathИскать через include_path при true; с PHP8.5 bool вместо int.
ВозвратМассив строк с сохранёнными переводами строки либо false с E_WARNING при отказе. Флагов FILE_IGNORE_NEW_LINES/FILE_SKIP_EMPTY_LINES здесь нет.
ПамятьВесь распакованный текст и элементы массива находятся в памяти. Маленький размер .gz не ограничивает размер этого массива.
Файл целиком становится массивом
  1. Сжатые строки на диске
  2. gzfile распаковывает всё
  3. Массив [0] → A1, [1] → B2
  4. foreach обрабатывает строки

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Получить массив двух строкСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$lines = gzfile($path);
if ($lines === false) { throw new RuntimeException('Read failed'); }
echo count($lines), "
", $lines[0];
Ожидаемый результат
2
A1

Индекс0 — первая строка. Для большого журнала выбирайте gzgets/gzread и обработку по частям.

Осознанно обработать пустые строкиСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/rows.gz';
file_put_contents($path, gzencode("A1\n\n0\n"));
$lines = gzfile($path);
if ($lines === false) { throw new RuntimeException('Read failed'); }
foreach ($lines as $line) {
    $value = rtrim($line, "\r\n");
    if ($value === '') { continue; }
    echo '[', $value, "]\n";
}
Ожидаемый результат
[A1]
[0]

Пропускаем только пустую строку, сохраняя0. rtrim с явными не удаляет значимые пробелы поля.

Дальше: gzgets; gzread; readgzfile.

gzseekПерейти к смещению в распакованных данных gz-потока.

PHP 4+ · zlib

gzseek(resource $stream, int $offset, int $whence = SEEK_SET): int

Перейти к смещению в распакованных данных gz-потока.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
offsetСмещение в распакованных байтах. При SEEK_SET — от начала, при SEEK_CUR — от текущей позиции.
whenceSEEK_SET default; SEEK_CUR поддерживается; SEEK_END не поддерживается.
Возврат0 при успехе, −1 при отказе; проверяют !== 0. Переход за конец сам по себе может не быть ошибкой.
ОграниченияНа чтении seek эмулируется и может быть очень медленным: приходится распаковывать предшествующие данные. При записи допустим переход вперёд, пропуск заполняется нулевыми байтами.
Смещение относится к исходному тексту
  1. A1\n занимает3байта
  2. gzseek на3
  3. Следующее чтение → B2
  4. Не адрес внутри сжатого файла

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Перейти ко второй строкеСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    var_dump(gzseek($stream, 3, SEEK_SET));
    echo gzgets($stream);
} finally { gzclose($stream); }
Ожидаемый результат
int(0)
B2

Для случайного доступа к тысячам записей монолитный gzip неудобен: подойдут индекс и независимо сжатые блоки либо база данных.

Увидеть нулевые байты при записи с пропускомСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/gap.gz';
$stream = gzopen($path, 'wb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    gzwrite($stream, 'A');
    if (gzseek($stream, 3) !== 0) { throw new RuntimeException('Seek failed'); }
    gzwrite($stream, 'B');
} finally { gzclose($stream); }
echo bin2hex(gzdecode(file_get_contents($path))), "\n";
Ожидаемый результат
41000042

Два нулевых байта — не пробелы и не удалённый участок. Такой приём обычно не нужен для текстового отчёта.

Дальше: gztell; gzrewind; gzread.

gztellПолучить текущую позицию в распакованных байтах.

PHP 4+ · zlib

gztell(resource $stream): int|false

Получить текущую позицию в распакованных байтах.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
ВозвратПоложение относительно начала несжатых данных либо false при ошибке. Ноль — правильная позиция начала. Это не число прочитанных байтов .gz на диске.
Чтение изменяет позицию
  1. Начало → 0
  2. Прочитали A1
  3. Позиция → 2
  4. Прочитали перевод строки → 3

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Посмотреть позицию после чтенияСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    var_dump(gztell($stream));
    gzread($stream, 2);
    var_dump(gztell($stream));
} finally { gzclose($stream); }
Ожидаемый результат
int(0)
int(2)

Позиция0 не ошибка. Сравнение === false сохраняет это различие.

Вернуться к сохранённой позицииСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    gzgets($stream);
    $bookmark = gztell($stream);
    if ($bookmark === false) { throw new RuntimeException('Position unavailable'); }
    echo gzgets($stream);
    if (gzseek($stream, $bookmark) !== 0) { throw new RuntimeException('Seek failed'); }
    echo gzgets($stream);
} finally { gzclose($stream); }
Ожидаемый результат
B2
B2

Закладка относится к неизменившемуся исходному содержимому. Возврат назад в gzip может повторно распаковать значительную часть файла.

Дальше: gzseek; gzrewind.

gzrewindВернуть указатель gz-потока к началу распакованных данных.

PHP 4+ · zlib

gzrewind(resource $stream): bool

Вернуть указатель gz-потока к началу распакованных данных.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
Возвратtrue при успехе, false при отказе. Эквивалентна gzseek(stream,0,SEEK_SET) по направлению действия, но возвращает bool вместо кода0.
ПрименениеПеречитать открытый читаемый файл. Не превращает ресурс wb в ресурс чтения и не отменяет ограничения режима записи.
Повторное чтение начинается сначала
  1. Прочитали A1
  2. gzrewind
  3. Позиция0
  4. Снова прочитали A1

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Прочитать первую строку повторноСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    echo gzgets($stream);
    if (!gzrewind($stream)) { throw new RuntimeException('Rewind failed'); }
    echo gzgets($stream);
} finally { gzclose($stream); }
Ожидаемый результат
A1
A1

Старые данные не дописываются и не копируются: меняется состояние чтения.

Сделать два небольших проходаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    foreach ([1, 2] as $pass) {
        if (!gzrewind($stream)) { throw new RuntimeException('Rewind failed'); }
        $count = 0;
        while (gzgets($stream) !== false) { $count++; }
        echo 'pass', $pass, '=', $count, "
";
    }
} finally { gzclose($stream); }
Ожидаемый результат
pass1=2
pass2=2

В учебном файле две короткие строки. Повторные проходы по большому архиву повторяют стоимость распаковки; по возможности совмещайте нужные вычисления в одном проходе.

Дальше: gzseek; gztell; gzopen.

gzpassthruВывести все оставшиеся распакованные данные открытого gz-потока.

PHP 4+ · zlib

gzpassthru(resource $stream): int

Вывести все оставшиеся распакованные данные открытого gz-потока.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
ДействиеЧитает от текущей позиции до EOF и пишет непосредственно в вывод. Возвращаемое число — количество распакованных байтов, а не сам текст.
КонтекстДля HTTP заголовки отправляют до тела. Распакованный вывод не следует маркировать Content-Encoding:gzip. Буферизация вывода способна накопить весь результат в памяти.
Вывод и возврат — разные каналы
  1. В потоке уже прочитано A1
  2. gzpassthru выводит остаток
  3. В переменную возвращается4
  4. Содержимое не возвращается строкой

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Отделить вывод от числа байтовСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    gzread($stream, 3);
    $count = gzpassthru($stream);
    echo 'bytes=', $count, "
";
} finally { gzclose($stream); }
Ожидаемый результат
B2
bytes=3

Мы пропустили первую строку с переводом; оставшиеся B2 и перевод занимают3байта.

Перехватить вывод только небольшого документаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    ob_start();
    try { $count = gzpassthru($stream); $text = ob_get_contents(); }
    finally { ob_end_clean(); }
    echo json_encode($text), "
", $count, "
";
} finally { gzclose($stream); }
Ожидаемый результат
"A1\nB2\n"
6

ob_start здесь демонстрирует связь вывода и строки. Для большого файла это снова расход памяти на весь документ; для небольшого содержимого обычно проще явное чтение.

Дальше: readgzfile; gzread; gzrewind.

readgzfileОткрыть gzip-файл, распаковать и сразу вывести его содержимое.

PHP 4+ · zlib

readgzfile(string $filename, bool $use_include_path = false): int|false

Открыть gzip-файл, распаковать и сразу вывести его содержимое.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
filenameПуть к файлу. Обычный несжатый файл также читается напрямую.
use_include_pathfalse default; с PHP8.5 bool вместо прежнего int.
Возврат / ошибкиЧисло выведенных распакованных байтов либо false; при отказе E_WARNING. Это вывод плюс статус, не функция получения строки.
HTTPПроверьте доступ к документу и тип содержимого до вывода. Content-Length нельзя брать из размера сжатого файла, если вы отдаёте распакованный текст.
Один вызов с побочным эффектом
  1. Путь report.gz
  2. Открытие и распаковка
  3. A1 и B2 уходят в вывод
  4. Возвращается6

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Вывести файл и затем статусСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/report.gz';
file_put_contents($path, gzencode("A1\nB2\n"));
$bytes = readgzfile($path);
if ($bytes === false) { throw new RuntimeException('Read failed'); }
echo 'bytes=', $bytes, "
";
Ожидаемый результат
A1
B2
bytes=6

Не пишите echo readgzfile(...) при выдаче документа: число результата случайно допишется к телу.

Убедиться в прозрачном чтении обычного файлаСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/plain.txt';
file_put_contents($path, "READY\n");
$bytes = readgzfile($path);
var_dump($bytes);
Ожидаемый результат
READY
int(6)

Успех этого вызова не подтверждает наличие gzip-заголовка. Для контролируемого скачивания чужие пути/обёртки не принимают напрямую.

Дальше: gzpassthru; gzfile; gzopen.

gzgetssПонять старый код, который читал gzip-строку и удалял HTML-теги; в PHP8 функция удалена.

PHP4–7; deprecated7.3; removed8.0 · zlib

Исторически: gzgetss(resource $stream, int $length, string $allowable_tags = ""): string|false

Понять старый код, который читал gzip-строку и удалял HTML-теги; в PHP8 функция удалена.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
streamДействующий ресурс от gzopen. Это не строка с путём и не объект DeflateContext. Закрытый ресурс в PHP8 вызывает TypeError.
lengthВ старом API максимальная длина читаемой порции; обработка потоковая, могла сохранять состояние удаления тегов между вызовами.
allowable_tagsСтрока разрешённых HTML-тегов. Сохранённые теги/атрибуты не обеспечивали безопасность HTML.
ВерсииУстарела в PHP7.3, удалена в PHP8.0. В новом коде не вызывать; подходящую обработку выбирают по смыслу данных.
Заменаgzgets + strip_tags для ограниченного преобразования текста не полностью повторяет исторический stateful-парсер. Для безопасного отображения исходного текста в HTML нужен htmlspecialchars; для разрешённого HTML — проверенный sanitizer с политикой.
Сначала понять желаемый результат
  1. Читаем строку gzgets
  2. Нужен текст с видимыми тегами? → htmlspecialchars
  3. Нужна текстовая выжимка? → отдельно разбор
  4. Не считать strip_tags защитой HTML

Файл на диске содержит сжатые байты, а открытый gz-поток отдаёт обычные распакованные данные. У потока есть текущая позиция: следующий вызов продолжает чтение от неё. rb открывает чтение, wb — запись с обнулением прежнего содержимого. Используйте свой проверенный путь: имя файла от посетителя нельзя без проверки передавать в файловую систему.

Показать пользовательский текст с тегами как текстСамостоятельный пример
<?php
declare(strict_types=1);

$path = __DIR__ . '/comment.gz';
file_put_contents($path, gzencode('<b>Hello</b>'));
$stream = gzopen($path, 'rb');
if ($stream === false) { throw new RuntimeException('Open failed'); }
try {
    $line = gzgets($stream);
    if ($line === false) { throw new RuntimeException('Read failed'); }
    echo htmlspecialchars($line, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'), "\n";
} finally { gzclose($stream); }
Ожидаемый результат
&lt;b&gt;Hello&lt;/b&gt;

Теги отображаются текстом в HTML. Это конкретный контекст вывода, не универсальное экранирование для JavaScript, SQL или URL.

Сделать простую текстовую выжимку известной строкиСамостоятельный пример
<?php
declare(strict_types=1);

$html = '<p>Order <b>25</b></p>';
echo strip_tags($html), "\n";
var_dump(function_exists('gzgetss'));
Ожидаемый результат
Order 25
bool(false)

Демонстрация PHP8.5.11. Для произвольного HTML нужно учитывать блоки, пробелы, сущности и повреждённую разметку; простое удаление тегов не полноценный HTML-to-text конвертер.

Дальше: gzgets; gzfile.

ob_gzhandlerПодключить штатный обработчик буфера вывода, который может сжать HTTP-ответ для клиента.

PHP4.0.4+ · zlib

ob_gzhandler(string $data, int $flags): string|false

Подключить штатный обработчик буфера вывода, который может сжать HTTP-ответ для клиента.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
dataОчередная часть буфера. При обычном ob_start обработчик вызывается системой вывода, а не вручную для каждой строки.
flagsБитовая маска фаз output-handler START/CLEAN/FLUSH/FINAL. Не уровень сжатия и не список допустимых HTTP-форматов.
ВозвратЗакодированная строка либо false, например если подходящее кодирование не выбрано. В цепочке ob false означает передачу исходного содержимого дальше, не успешный gzip.
Подключениеob_start("ob_gzhandler") до вывода. Требуется zlib. Не сочетать с zlib.output_compression; официальное руководство предпочитает эту INI-настройку обработчику.
HTTPПри сжатии выставляются Content-Encoding и Vary:Accept-Encoding. Нельзя заранее задавать Content-Length исходного текста. Учитывайте прокси, кэш и уже сжатые форматы.
Сначала обычный ответ, затем транспортное кодирование
  1. echo формирует текст READY
  2. Буфер собирает/передаёт текст обработчику
  3. Обработчик выбирает gzip/deflate/без сжатия
  4. Клиент декодирует байты и видит тот же текст

У HTTP есть две разные вещи: исходный текст ответа и байты, отправляемые по сети. Content-Type описывает содержимое, Content-Encoding — применённое к нему кодирование. Заголовок сам ничего не сжимает. Если отправить обычный текст с Content-Encoding:gzip, клиент попробует распаковать несжатые байты и получит ошибку.

В PHP8.5.11 выбор zlib проверяет наличие подстроки gzip, затем deflate; это не полный разбор весов Accept-Encoding. Локальная проверка воспроизводит gzip даже для gzip;q=0. Нельзя обещать корректную обработку всех вариантов negotiation этой функцией. Для публичной инфраструктуры обычно настраивают один отвечающий за сжатие веб-сервер/proxy и проверяют его договор, исключая двойное сжатие.

Сохранить обычный вывод без HTTP-negotiationСамостоятельный пример
<?php
declare(strict_types=1);

if (!ob_start('ob_gzhandler')) { throw new RuntimeException('Buffer unavailable'); }
echo "READY\n";
ob_end_flush();
Ожидаемый результат
READY

Обычный CLI не присылает Accept-Encoding. Этот опыт проверяет передачу текста, не работу HTTP-сжатия.

Подключить обработчик к маленькому HTTP-ответуПример для указанного окружения
<?php
// Самостоятельный HTTP endpoint; автоматическое сжатие PHP отключено.
if (ini_get('zlib.output_compression')) {
    throw new RuntimeException('Choose one compression layer');
}
if (!ob_start('ob_gzhandler')) { throw new RuntimeException('Buffer unavailable'); }
header('Content-Type: text/plain; charset=UTF-8');
echo "Order 25: READY\n";
ob_end_flush();
Ожидаемый результат
Order 25: READY

После декодирования клиент видит Order25:READY. На отдельном localhost HTTP-стенде проверены gzip, deflate и отсутствие согласованного кодирования. В общем списке это HTTP-контекст, поэтому синтаксис отмечен отдельно от интеграционного выполнения.

Настроить автоматическое сжатие до выводаПример для указанного окружения
<?php
// Настраивается до любого вывода; reverse proxy не должен сжимать повторно.
if (ini_set('zlib.output_compression', '1') === false) {
    throw new RuntimeException('Compression unavailable');
}
header('Content-Type: text/plain; charset=UTF-8');
echo "Order 25: READY\n";
Ожидаемый результат
Order 25: READY

Это альтернатива предыдущему endpoint, не дополнительный ob_gzhandler поверх него. Настройка действует только на запрос. Проверяйте возможность ini_set; системный сервер может запрещать изменение.

Сжатие полезно для повторяющегося текста HTML/JSON/CSS, но стоит CPU. JPEG/ZIP обычно уже сжаты. Размер сжатого ответа может раскрывать информацию, если смешивать секрет и управляемое злоумышленником отражение; для таких endpoint требуется отдельная политика, а не бездумное включение везде. Дорогую генерацию отчёта сжатие само по себе не ускоряет. Буферы, фазы и порядок вывода.

Дальше: zlib_get_coding_type; gzencode.

zlib_get_coding_typeПосмотреть, какой тип кодирования выбран zlib для текущего вывода.

PHP4.3.2+ · zlib

zlib_get_coding_type(): string|false

Посмотреть, какой тип кодирования выбран zlib для текущего вывода.

Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.

В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.

Часть вызоваДоговор и границы
АргументыНет. Функция смотрит состояние текущего PHP-запроса.
Возврат"gzip", "deflate" либо false. Не определяет формат произвольной строки/файла.
Момент вызоваПри ob_gzhandler выбор может произойти только при обработке буфера. До этого false не доказывает, что будущий ответ останется несжатым.
Граница наблюденияНе видит последующее сжатие reverse proxy/CDN и не доказывает, какие байты реально получил клиент. Для этого смотрят HTTP-заголовки и тело на стороне клиента.
Состояние внутри PHP и ответ снаружи
  1. До выбора может быть false
  2. Инициализировано gzip-сжатие
  3. Функция возвращает gzip
  4. Клиент отдельно проверяет Content-Encoding и тело

У HTTP есть две разные вещи: исходный текст ответа и байты, отправляемые по сети. Content-Type описывает содержимое, Content-Encoding — применённое к нему кодирование. Заголовок сам ничего не сжимает. Если отправить обычный текст с Content-Encoding:gzip, клиент попробует распаковать несжатые байты и получит ошибку.

В PHP8.5.11 выбор zlib проверяет наличие подстроки gzip, затем deflate; это не полный разбор весов Accept-Encoding. Локальная проверка воспроизводит gzip даже для gzip;q=0. Нельзя обещать корректную обработку всех вариантов negotiation этой функцией. Для публичной инфраструктуры обычно настраивают один отвечающий за сжатие веб-сервер/proxy и проверяют его договор, исключая двойное сжатие.

Проверить обычный CLI без сжатияСамостоятельный пример
<?php
declare(strict_types=1);

var_dump(zlib_get_coding_type());
$packed = gzencode('READY');
var_dump(zlib_get_coding_type());
echo gzdecode($packed), "\n";
Ожидаемый результат
bool(false)
bool(false)
READY

Создание строки gzencode не включает HTTP-сжатие и не меняет coding type. Это две разные задачи.

Вывести выбранный тип в собственном HTTP-ответеПример для указанного окружения
<?php
if (ini_set('zlib.output_compression', '1') === false) {
    throw new RuntimeException('Compression unavailable');
}
$coding = zlib_get_coding_type();
header('Content-Type: text/plain; charset=UTF-8');
echo 'coding=', $coding === false ? 'none' : $coding, "\n";

Для запроса Accept-Encoding:gzip декодированное тело coding=gzip; для deflate — coding=deflate; без согласования — coding=none. Варианты выполнены на отдельном HTTP-стенде. Не меняйте Content-Encoding вручную по строке, возвращённой здесь.

У функции нет аналога «проверь всё HTTP-сжатие». Она удобна для диагностики текущего слоя PHP; наблюдаемое тело клиента важнее одного внутреннего флага.

Дальше: ob_gzhandler; zlib_decode.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.