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

Дерево руководства
Глава 104 · От основ к практике
Zlib: gzip-файлы, сжатие строк и потоков
От маленькой строки до сжатой выгрузки и HTTP: все функции, форматы, контексты, ограничения и реальные проверки.
Отчёт стал большим: уменьшаем байты, сохраняя исходные данные
Текст остаётся тем же, меняется его упаковка
Отчёт READY сжимается перед хранением или передачей. Получатель должен знать формат и проверить результат распаковки.
- 1$text = READY↓
Обычные исходные байты; их смысл известен приложению.
- 2gzencode($text)↓
Получается бинарный поток формата gzip с собственной оболочкой.
- 3Хранение или передача↓
Сжатые байты не преобразуют как обычный текст и не называют ZIP-архивом.
- 4gzdecode → READY
Проверяем false, размер и точное восстановление ожидаемых данных.
Сжатие не шифрует. Короткий READY может стать больше из-за заголовков; большой распакованный результат требует отдельных ограничений памяти и времени.
Магазин каждый день передаёт поставщику текстовый отчёт. В нём повторяются имена полей и похожие строки. Сжатие кодирует эти повторы компактнее; получатель должен применить подходящую распаковку и получить тот же текст. Это полезно для обмена и хранения, но не скрывает данные от посторонних.
Строка PHP может содержать текст или любые байты. $data — переменная, = сохраняет результат, имя со скобками вызывает функцию. Аргументы разделяют запятыми; echo выводит данные, strlen считает байты. === false отличает ошибку от пустой строки. Сжатые байты обычно не выводят прямо в HTML: их сохраняют или передают по договорённому формату.
В длинных примерах [] создаёт массив настроек, foreach перебирает части, .= дописывает строку. if выбирает действие по условию; try/finally освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.
- Исходный текст: READY
- Компрессор → бинарные байты
- Передача/хранение по договорённому формату
- Декомпрессор → снова 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 — разные договоры
- DEFLATE сжимает данные
- Raw: только поток DEFLATE
- Zlib: своя оболочка/контроль
- Gzip: другая оболочка/контроль
| Формат | Сжать → распаковать | Где встречается |
|---|---|---|
| Gzip RFC1952 | gzencode → gzdecode | .gz, HTTP Content-Encoding:gzip. |
| Zlib RFC1950 | gzcompress → gzuncompress | Двоичный протокол с zlib-оболочкой; HTTP deflate. |
| Raw DEFLATE RFC1951 | gzdeflate → gzinflate | Участок более сложного контейнера/протокола, который сам описывает метаданные. |
| Выбранный/распознаваемый формат | zlib_encode / zlib_decode | Явный encoding у компрессора; распознавание поддержанных оболочек у декодера. |
| ZIP | ZipArchive из отдельного расширения | Контейнер с именами нескольких файлов, каталогом, методами сжатия и метаданными. Ни 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 может повторно распаковывать пройденные данные и быть медленной. Экономия памяти требует не только читать порциями, но и не собирать их затем в одну огромную строку.
- Прочитали маленький chunk
- Если дописывать его в общий result, result растёт
- Если обработать и освободить — остаётся рабочая порция
- Внутренние буферы и размер раскрытия тоже учитываются
Установка, требования и проверка своего PHP
Расширение использует библиотеку zlib. Для PHP8.4+ официально требуется zlib не ниже1.2.11; раньше минимумом была1.2.0.4. При сборке Unix включают --with-zlib[=DIR]; это параметр сборки PHP, не функция приложения. В Windows-поставке PHP поддержка встроена, отдельный DLL для этих функций обычно не загружается. Наличие PHP само по себе всё же лучше проверить на конкретном сервере.
- Проверить extension_loaded zlib
- Посмотреть фактическую версию библиотеки
- Выполнить маленький round-trip
- Отдельно проверить 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.
- Проверить proxy/web-server
- Выбрать слой сжатия
- Настроить до отправки тела
- Клиент проверяет заголовки и декодируемость
Все константы: формат, стратегия, завершение и статус
| Группа | Значения и смысл |
|---|---|
| Формат | 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, не криптографические режимы. |
| Flush | ZLIB_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 — несовместимая версия библиотеки. |
- inflate_add может дать часть текста
- inflate_get_status сообщает состояние
- Только STREAM_END подтверждает конец этого потока
- Размер, остаток и бизнес-формат проверяются отдельно
Таблица перечисляет все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.
- gzopen → ресурс файла
- deflate_init → DeflateContext
- inflate_init → InflateContext
- Каждому виду — собственные функции
Контексты не являются переносимой формой задания для очереди. В очередь передают данные/параметры и создают новый контекст в worker. Закрытие файла и потеря ссылки на контекст — разные механизмы освобождения.
DeflateContext: непрозрачный объект состояния, создаваемый фабрикой
Это final-класс встроенного расширения, введённый в PHP8. Он не описывает вашу бизнес-сущность и не предназначен для наследования. Публичный new не создаёт рабочий контекст; используйте deflate_init. В классе нет пользовательского набора методов/полей для ручной настройки; функции принимают сам объект.
- Фабрика deflate_init
- Получен DeflateContext
- Вызовы deflate_add продолжают работу
- Новый независимый документ → новое осознанное состояние
<?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. В классе нет пользовательского набора методов/полей для ручной настройки; функции принимают сам объект.
- Фабрика inflate_init
- Получен InflateContext
- Вызовы inflate_add продолжают работу
- Новый независимый документ → новое осознанное состояние
<?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 перед ними, перевод кодировки или запись через неподходящую текстовую обработку портят поток. При ошибке сначала сравните реальные байты транспорта и согласованный формат. Нельзя без договора отрезать всё до первого похожего заголовка: можно скрыть ошибку сервера или принять не тот документ.
- Ограничить вход и время
- Выбрать согласованный формат
- Проверить отказ/завершение и размер выхода
- Проверить структуру JSON/CSV и бизнес-правила
В PHP8.5.11/zlib1.3.2 max_length у строковых декодеров в некоторых случаях превышается:48байт результата могут вернуться при лимите47. В карточках есть воспроизводимый пример и постпроверка strlen. Постпроверка выявляет превышение, но не отменяет память, уже выделенную декодером. Для недоверенного сжатого входа нужен также процессный бюджет, лимит входа/времени и архитектура с контролем ресурсов.
inflate_add может выдать часть полезного текста даже для усечённого потока. Проверяйте ZLIB_STREAM_END, остаток входа, количество разрешённых members и checksum по договору. gzeof сам по себе допускает состояние ошибки. Префикс1F8B или расширение.gz не подтверждает ни полную распаковку, ни безопасность содержимого.
Сжатие не шифрует и не заменяет проверку подлинности. Повторная упаковка уже сжатого файла часто тратит CPU без пользы. Измеряйте полный путь — чтение, сжатие, передачу, распаковку, запись — на типичных данных.
Практика: сжатая выгрузка из магазина
- Строка READY → gzip → та же строка
- Две строки заказа → файл.gz
- Построчное чтение → обработка каждой записи
- Поток интеграции → проверка окончания и лимитов
Первый шаг: повторите небольшой 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 не обещает ускорить передачу любой маленькой строки. |
| encoding | ZLIB_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-архивом нескольких файлов. |
- Строка report содержит повторения
- Выбран формат zlib
- gzcompress возвращает бинарные байты
- 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 не обещает ускорить передачу любой маленькой строки. |
| encoding | ZLIB_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-архивом нескольких файлов. |
- Строка report содержит повторения
- Выбран формат gzip
- gzencode возвращает бинарные байты
- 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 не обещает ускорить передачу любой маленькой строки. |
| encoding | ZLIB_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-архивом нескольких файлов. |
- Строка report содержит повторения
- Выбран формат raw DEFLATE
- gzdeflate возвращает бинарные байты
- 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. Не используйте его как бюджет памяти сервиса: ограничивайте вход, выход, время и ресурсы процесса. |
- Получены байты zlib
- gzuncompress пытается восстановить строку
- false означает отказ, пустая строка может быть успехом
- Приложение проверяет допустимую длину и структуру результата
<?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. Не используйте его как бюджет памяти сервиса: ограничивайте вход, выход, время и ресурсы процесса. |
- Получены байты gzip
- gzdecode пытается восстановить строку
- false означает отказ, пустая строка может быть успехом
- Приложение проверяет допустимую длину и структуру результата
<?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. Не используйте его как бюджет памяти сервиса: ограничивайте вход, выход, время и ресурсы процесса. |
- Получены байты raw DEFLATE
- gzinflate пытается восстановить строку
- false означает отказ, пустая строка может быть успехом
- Приложение проверяет допустимую длину и структуру результата
<?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. |
- Партнёр ожидает gzip
- Передаём ZLIB_ENCODING_GZIP
- zlib_encode создаёт соответствующую оболочку
- Парный получатель использует 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_length | 0 без пользовательского лимита; положительное значение ограничивает декодирование, но в PHP8.5.11 не гарантирует точное совпадение верхней границы буфера. Проверяйте длину результата отдельно. |
| Возврат / ошибки | Строка либо false с E_WARNING; отрицательный лимит даёт ValueError. Успешное декодирование не проверяет бизнес-схему данных и не аутентифицирует отправителя. |
- Формат входа из разрешённого набора
- zlib_decode распознаёт поддерживаемую оболочку
- Получаем исходные байты
- Отдельно проверяем длину, 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 / memory | level -1..9, default -1; memory 1..9, default 8. memory — уровень рабочих структур zlib, не лимит памяти PHP в байтах. |
| options.window / strategy | window 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-заголовка; не обещайте идентичность каждого байта между ОС. |
- Создаём context для gzip
- Передаём первую часть
- Контекст помнит уже встреченные фрагменты
- Последнюю часть завершаем 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.
<?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_mode | NO_FLUSH/PARTIAL_FLUSH/SYNC_FLUSH/FULL_FLUSH/BLOCK/FINISH; неверный режим даёт ValueError в текущем PHP. |
| Возврат | Сжатая часть, возможно пустая строка, либо false с предупреждением. Все успешные части передают получателю в исходном порядке. |
| Завершение | FINISH завершает поток. PHP8.5.11 после успешного окончания сбрасывает deflate-контекст; следующий FINISH может начать новый отдельный поток. Это не продолжение старого содержимого. |
- Часть A → add(NO_FLUSH)
- Часть B → add(NO_FLUSH)
- Конец → add(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.
| Режим | Что означает |
|---|---|
| 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 освобождает ресурс даже при обычном исключении. Вызовы и возвращаемые значения и потоковое чтение объясняются отдельно.
| Часть вызова | Договор и границы |
|---|---|
| encoding | ZLIB_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 способен породить большой выход. |
- Выбираем gzip
- inflate_init создаёт контекст
- Передаём поступающие байты в inflate_add
- Проверяем конец потока и общий размер результата
Контекст хранит состояние сжатия между вызовами: уже увиденную историю и служебные данные алгоритма. Его создаёт 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 лениво сбрасывает состояние. |
- Получили первый бинарный chunk
- inflate_add вернул доступный текст или пустую строку
- Последняя часть обработана с FINISH
- Приложение проверило 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 может означать нехватку следующей порции/невозможность продвижения, не обязательно повреждение. |
- Декодер вернул строку
- Читаем status
- STREAM_END подтверждает конец потока
- Другой статус требует ещё ввода или отказа по условиям
<?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. |
- В буфере gzip(one) + gzip(two)
- Один inflate_add заканчивает первый member
- read_len показывает длину первого префикса
- Хвост нужно отклонить или обработать явно
<?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: счётчик учитывает сжатую оболочку, а не только полезный текст.
<?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-формат. |
| mode | rb — чтение; wb — запись с обнулением; ab — добавление. Не поддерживается чтение и запись одним режимом через +. К режиму записи можно добавить уровень0..9 и f (filtered) либо h (Huffman only), например wb9. |
| use_include_path | false по умолчанию; true разрешает поиск через include_path. С PHP8.5 тип bool вместо прежнего int. Для конкретной выгрузки обычно нужен явный путь. |
| Возврат | Ресурс потока либо false. Ресурс закрывают gzclose в finally. Режим и уровень меняют CPU/степень сжатия, не смысл исходных данных. |
- report.gz на диске
- gzopen rb → ресурс
- gzread отдаёт A1
- 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Закрыть 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. |
- Записаны исходные байты
- 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'); }
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.
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 перед записью обычно создаёт ненужное двойное сжатие. |
| length | null — вся строка; положительное значение ограничивает число исходных байтов. С PHP8 параметр nullable. |
| Возврат | Число записанных несжатых байтов либо false. До PHP7.4 ошибка возвращала0. Проверяйте также короткую запись и0, а не только false. |
| Псевдоним | gzputs — другое имя gzwrite, контракт и реализация одинаковые. |
- Передать строку READY
- Поток сжимает данные
- Получить5 — исходные байты
- 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 после короткой записи нельзя: получится дубликат.
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 перед записью обычно создаёт ненужное двойное сжатие. |
| length | null — вся строка; положительное значение ограничивает число исходных байтов. С PHP8 параметр nullable. |
| Возврат | Число записанных несжатых байтов либо false. До PHP7.4 ошибка возвращала0. Проверяйте также короткую запись и0, а не только false. |
| Псевдоним | gzputs — другое имя gzwrite, контракт и реализация одинаковые. |
- Передать строку READY
- Поток сжимает данные
- Получить5 — исходные байты
- 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 после короткой записи нельзя: получится дубликат.
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. Короткая строка не обязана означать ошибку. |
- report.gz
- gzread 2 → A1
- Следующий вызов продолжает после A1
- Пустая строка и 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 при ошибке/отсутствии следующей строки. Последняя строка может не иметь . Часть длинной строки ещё не является целой записью. |
- Первый вызов → A1 и перевод строки
- Второй → B2 и перевод строки
- Третий → false
- 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.
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. |
- В потоке A1
- Первый gzgetc → A
- Второй → 1
- Каждый вызов сдвигает позицию
Файл на диске содержит сжатые байты, а открытый 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-инструмент.
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 в общем потоковом контракте. Это не контрольная сумма и не свидетельство успешной загрузки. |
- Поток открыт
- Читаем данные
- Пробуем читать после конца
- 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 не ограничивает размер этого массива. |
- Сжатые строки на диске
- gzfile распаковывает всё
- Массив [0] → A1, [1] → B2
- 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 — от текущей позиции. |
| whence | SEEK_SET default; SEEK_CUR поддерживается; SEEK_END не поддерживается. |
| Возврат | 0 при успехе, −1 при отказе; проверяют !== 0. Переход за конец сам по себе может не быть ошибкой. |
| Ограничения | На чтении seek эмулируется и может быть очень медленным: приходится распаковывать предшествующие данные. При записи допустим переход вперёд, пропуск заполняется нулевыми байтами. |
- A1\n занимает3байта
- gzseek на3
- Следующее чтение → B2
- Не адрес внутри сжатого файла
Файл на диске содержит сжатые байты, а открытый 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Получить текущую позицию в распакованных байтах.
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 на диске. |
- Начало → 0
- Прочитали A1
- Позиция → 2
- Прочитали перевод строки → 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 может повторно распаковать значительную часть файла.
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 в ресурс чтения и не отменяет ограничения режима записи. |
- Прочитали A1
- gzrewind
- Позиция0
- Снова прочитали 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
В учебном файле две короткие строки. Повторные проходы по большому архиву повторяют стоимость распаковки; по возможности совмещайте нужные вычисления в одном проходе.
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. Буферизация вывода способна накопить весь результат в памяти. |
- В потоке уже прочитано A1
- gzpassthru выводит остаток
- В переменную возвращается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_path | false default; с PHP8.5 bool вместо прежнего int. |
| Возврат / ошибки | Число выведенных распакованных байтов либо false; при отказе E_WARNING. Это вывод плюс статус, не функция получения строки. |
| HTTP | Проверьте доступ к документу и тип содержимого до вывода. Content-Length нельзя брать из размера сжатого файла, если вы отдаёте распакованный текст. |
- Путь report.gz
- Открытие и распаковка
- A1 и B2 уходят в вывод
- Возвращается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 с политикой. |
- Читаем строку gzgets
- Нужен текст с видимыми тегами? → htmlspecialchars
- Нужна текстовая выжимка? → отдельно разбор
- Не считать 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); }
Ожидаемый результат
<b>Hello</b>
Теги отображаются текстом в 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 конвертер.
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 исходного текста. Учитывайте прокси, кэш и уже сжатые форматы. |
- echo формирует текст READY
- Буфер собирает/передаёт текст обработчику
- Обработчик выбирает gzip/deflate/без сжатия
- Клиент декодирует байты и видит тот же текст
У HTTP есть две разные вещи: исходный текст ответа и байты, отправляемые по сети. Content-Type описывает содержимое, Content-Encoding — применённое к нему кодирование. Заголовок сам ничего не сжимает. Если отправить обычный текст с Content-Encoding:gzip, клиент попробует распаковать несжатые байты и получит ошибку.
В PHP8.5.11 выбор zlib проверяет наличие подстроки gzip, затем deflate; это не полный разбор весов Accept-Encoding. Локальная проверка воспроизводит gzip даже для gzip;q=0. Нельзя обещать корректную обработку всех вариантов negotiation этой функцией. Для публичной инфраструктуры обычно настраивают один отвечающий за сжатие веб-сервер/proxy и проверяют его договор, исключая двойное сжатие.
<?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-сжатия.
<?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-заголовки и тело на стороне клиента. |
- До выбора может быть false
- Инициализировано gzip-сжатие
- Функция возвращает gzip
- Клиент отдельно проверяет Content-Encoding и тело
У HTTP есть две разные вещи: исходный текст ответа и байты, отправляемые по сети. Content-Type описывает содержимое, Content-Encoding — применённое к нему кодирование. Заголовок сам ничего не сжимает. Если отправить обычный текст с Content-Encoding:gzip, клиент попробует распаковать несжатые байты и получит ошибку.
В PHP8.5.11 выбор zlib проверяет наличие подстроки gzip, затем deflate; это не полный разбор весов Accept-Encoding. Локальная проверка воспроизводит gzip даже для gzip;q=0. Нельзя обещать корректную обработку всех вариантов negotiation этой функцией. Для публичной инфраструктуры обычно настраивают один отвечающий за сжатие веб-сервер/proxy и проверяют его договор, исключая двойное сжатие.
<?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. Это две разные задачи.
<?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. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.


