Как создать файл .gz с помощью PHP? - PullRequest
51 голосов
/ 20 мая 2011

Я бы хотел сжать файл на моем сервере с помощью PHP. У кого-нибудь есть пример, который бы вводил файл и выводил сжатый файл?

Ответы [ 8 ]

95 голосов
/ 20 мая 2011

Этот код делает трюк

// Name of the file we're compressing
$file = "test.txt";

// Name of the gz file we're creating
$gzfile = "test.gz";

// Open the gz file (w9 is the highest compression)
$fp = gzopen ($gzfile, 'w9');

// Compress the file
gzwrite ($fp, file_get_contents($file));

// Close the gz file and we're done
gzclose($fp);
81 голосов
/ 31 марта 2014

Другие ответы здесь загружают весь файл в память во время сжатия, что приведет к ошибкам out of memory в больших файлах.Приведенная ниже функция должна быть более надежной для больших файлов, так как она читает и записывает файлы по 512 КБ.

/**
 * GZIPs a file on disk (appending .gz to the name)
 *
 * From /7304781/kak-sozdat-fail-gz-s-pomoschy-php
 * Based on function by Kioob at:
 * http://www.php.net/manual/en/function.gzwrite.php#34955
 * 
 * @param string $source Path to file that should be compressed
 * @param integer $level GZIP compression level (default: 9)
 * @return string New filename (with .gz appended) if success, or false if operation fails
 */
function gzCompressFile($source, $level = 9){ 
    $dest = $source . '.gz'; 
    $mode = 'wb' . $level; 
    $error = false; 
    if ($fp_out = gzopen($dest, $mode)) { 
        if ($fp_in = fopen($source,'rb')) { 
            while (!feof($fp_in)) 
                gzwrite($fp_out, fread($fp_in, 1024 * 512)); 
            fclose($fp_in); 
        } else {
            $error = true; 
        }
        gzclose($fp_out); 
    } else {
        $error = true; 
    }
    if ($error)
        return false; 
    else
        return $dest; 
} 
20 голосов
/ 20 мая 2011

Кроме того, вы можете использовать php's wrappers , компрессионные .С минимальным изменением в коде вы сможете переключаться между gzip, bzip2 или zip.

$input = "test.txt";
$output = $input.".gz";

file_put_contents("compress.zlib://$output", file_get_contents($input));

изменить compress.zlib:// на compress.zip:// для сжатия zip (см. комментарий к этому ответу о сжатии zip) или compress.bzip2:// к сжатию bzip2.

5 голосов
/ 04 декабря 2014

Простой вкладыш с gzencode () :

gzencode(file_get_contents($file_name));
3 голосов
/ 07 июня 2015

Если вы хотите просто распаковать файл, это работает и не вызывает проблем с памятью:

$bytes = file_put_contents($destination, gzopen($gzip_path, r));
1 голос
/ 10 февраля 2017

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

exec("gzip ".$filename);

NB: Обязательно правильно санируйте переменную $filename перед ее использованием, особенно если она поступает от пользовательского ввода (но не только).Он может использоваться для запуска произвольных команд, например, с помощью чего-то вроде my-file.txt && anothercommand (или my-file.txt; anothercommand).

0 голосов
/ 15 мая 2019

Вот улучшенная версия.Я избавился от всех вложенных операторов if / else, что привело к снижению цикломатической сложности, лучше обрабатывать ошибки с помощью исключений вместо отслеживания состояния логической ошибки, подсказок некоторых типов, и я выручаю, если файл имеет расширение gzуже.С точки зрения строк кода он стал немного длиннее, но он стал более читабельным.

/**
 * Compress a file using gzip
 *
 * Rewritten from Simon East's version here:
 * https://stackoverflow.com/a/22754032/3499843
 *
 * @param string $inFilename Input filename
 * @param int    $level      Compression level (default: 9)
 *
 * @throws Exception if the input or output file can not be opened
 *
 * @return string Output filename
 */
function gzcompressfile(string $inFilename, int $level = 9): string
{
    // Is the file gzipped already?
    $extension = pathinfo($inFilename, PATHINFO_EXTENSION);
    if ($extension == "gz") {
        return $inFilename;
    }

    // Open input file
    $inFile = fopen($inFilename, "rb");
    if ($inFile === false) {
        throw new \Exception("Unable to open input file: $inFilename");
    }

    // Open output file
    $gzFilename = $inFilename.".gz";
    $mode = "wb".$level;
    $gzFile = gzopen($gzFilename, $mode);
    if ($gzFile === false) {
        fclose($inFile);
        throw new \Exception("Unable to open output file: $gzFilename");
    }

    // Stream copy
    $length = 512 * 1024; // 512 kB
    while (!feof($inFile)) {
        gzwrite($gzFile, fread($inFile, $length));
    }

    // Close files
    fclose($inFile);
    gzclose($gzFile);

    // Return the new filename
    return $gzFilename;
}
0 голосов
/ 19 ноября 2018

copy ('file.txt', 'compress.zlib: //'. 'File.txt.gz');См. документацию

...