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

Использование gzpassthru для вывода сжатых данных
Раздел: Сжатие
gzpassthru(resource $stream): int
Описание функции gzpassthru

Функция gzpassthru() предназначена для чтения и вывода оставшейся части файлового указателя gzip-файла. Она выводит все данные от текущей позиции указателя до конца файла (EOF). После выполнения функция автоматически закрывает файл.

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

Аргументы функции:
$stream (обязательный) - ресурс gz-файла, полученный после успешного открытия с помощью gzopen().

Возвращает количество распакованных байт, прочитанных с файлового указателя и переданных на вывод, или false в случае ошибки.

Простые примеры использования
Пример 1: Базовое чтение файла
$filename = 'example.txt.gz';
$handle = gzopen($filename, 'rb');
if ($handle) {
    echo gzpassthru($handle); // Выводит содержимое распакованным
}
Содержимое файла example.txt, сжатого в gz...
Пример 2: Чтение после перемещения указателя
$handle = gzopen('data.gz', 'rb');
gzread($handle, 10); // Пропускаем первые 10 байт распакованных данных
echo 'Остальные данные: ';
echo gzpassthru($handle); // Выводит все данные с 11-го байта до конца
Остальные данные: ... (распакованное содержимое с 11-го байта)
Похожие функции в PHP

gzread() - читает указанное количество байт из gz-файла. Позволяет контролировать объем считываемых данных, в отличие от gzpassthru, которая читает до конца.

readgzfile() - читает и выводит весь gz-файл. Функция похожа на комбинацию gzopen(), gzpassthru() и gzclose(), но не требует явного открытия и закрытия файла.

gzinflate() - распаковывает сырую сжатую строку без заголовков gzip. Используется для работы со сжатыми данными в памяти.

Выбор функции зависит от задачи: gzpassthru удобна для прямого вывода, gzread - для обработки частями, readgzfile - для простого вывода всего файла, gzinflate - для работы со строками.

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

Gzpassthru в Python

import gzip
with gzip.open('example.txt.gz', 'rb') as f:
    print(f.read().decode())  # Чтение всего содержимого
Содержимое файла...
JavaScript (Node.js)
const zlib = require('zlib');
const fs = require('fs');
const gunzip = zlib.createGunzip();
const input = fs.createReadStream('file.gz');
input.pipe(gunzip).pipe(process.stdout);
Содержимое файла в stdout...

Gzpassthru в MySQL

Прямого аналога нет, но есть функции для работы со сжатыми данными, например, COMPRESS() и UNCOMPRESS() для строк.

SELECT UNCOMPRESS(compressed_column) FROM table;
Типичные ошибки
Ошибка 1: Передача неверного типа ресурса
$file = fopen('test.txt', 'r');
echo gzpassthru($file); // Не gz-ресурс
Warning: gzpassthru(): supplied resource is not a valid stream resource
Ошибка 2: Попытка повторного использования закрытого ресурса
$gz = gzopen('file.gz', 'rb');
gzpassthru($gz); // Файл автоматически закрыт
echo gzread($gz, 10); // Ошибка
Warning: gzread(): %d is not a valid stream resource
Ошибка 3: Отсутствие файла
$handle = @gzopen('missing.gz', 'rb');
if (!$handle) {
    echo 'Ошибка открытия файла';
} else {
    gzpassthru($handle);
}
Ошибка открытия файла
Изменения в последних версиях PHP

В PHP 8.0.0 функция gzpassthru() теперь выбрасывает исключение ValueError, если параметр $stream не является ресурсом. Ранее выдавалась ошибка уровня E_WARNING.

Других значительных изменений в поведении функции в последних версиях PHP не было. Функция сохраняет обратную совместимость.

Расширенные примеры
Пример 1: Отдача gz-файла с заголовками HTTP
Пример php
$gzFile = 'archive.tar.gz';
$handle = gzopen($gzFile, 'rb');
if ($handle) {
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="archive.tar"');
    header('Content-Encoding: gzip'); // Указываем, что содержимое сжато
    gzpassthru($handle); // Отправляем сжатые данные как есть
}
Пример 2: Логирование с последующим выводом
Пример php
$logGz = 'app.log.gz';
$handle = gzopen($logGz, 'rb');
$firstLine = gzgets($handle); // Читаем первую строку
$bytesRead = gzpassthru($handle); // Выводим остальное
file_put_contents('bytes.log', "Прочитано байт: $bytesRead");
Пример 3: Построчная обработка с gzpassthru

Построчная обработка невозможна, так как gzpassthru выводит все сразу. Для построчной обработки следует использовать gzgets() в цикле.

Пример php
$handle = gzopen('large.log.gz', 'rb');
while (!gzeof($handle)) {
    $line = gzgets($handle);
    // Обработка строки
}
gzclose($handle);

PHP gzpassthru function comments

En
Gzpassthru Output all remaining data on a gz-file pointer