如何使用 PHP 创建 .gz 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6073397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 23:17:05  来源:igfitidea点击:

How do you create a .gz file using PHP?

phpcompressiongzip

提问by AlBeebe

I would like to gzip compress a file on my server using PHP. Does anyone have an example that would input a file and output a compressed file?

我想使用 PHP 对我的服务器上的文件进行 gzip 压缩。有没有人有一个例子可以输入一个文件并输出一个压缩文件?

回答by AlBeebe

This code does the trick

这段代码可以解决问题

// 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);

回答by Simon East

The other answers here load the entire file into memory during compression, which will cause 'out of memory' errors on large files. The function below should be more reliable on large files as it reads and writes files in 512kb chunks.

此处的其他答案在压缩期间将整个文件加载到内存中,这将导致大文件出现“内存不足”错误。下面的函数在大文件上应该更可靠,因为它以 512kb 的块读取和写入文件。

/**
 * GZIPs a file on disk (appending .gz to the name)
 *
 * From http://stackoverflow.com/questions/6073397/how-do-you-create-a-gz-file-using-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; 
} 

回答by Carlos Campderrós

Also, you could use php's wrappers, the compression ones. With a minimal change in the code you would be able to switch between gzip, bzip2 or zip.

此外,您可以使用 php 的包装器,即压缩器。只需对代码进行最小的更改,您就可以在 gzip、bzip2 或 zip 之间切换。

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

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

change compress.zlib://to compress.zip://for zip compression(see comment to this answer about zip compression), or to compress.bzip2://to bzip2 compression.

变化compress.zlib://compress.zip://进行zip压缩(看到这个答案约ZIP压缩评论),或者compress.bzip2://以压缩的bzip2。

回答by dtbarne

Simple one liner with gzencode():

带有gzencode() 的简单单行

gzencode(file_get_contents($file_name));

回答by Frank Carey

If you are looking to just unzip a file, this works and doesn't cause issues with memory:

如果您只想解压缩文件,这可以工作并且不会导致内存问题:

$bytes = file_put_contents($destination, gzopen($gzip_path, r));

回答by Niavlys

It's probably obvious to many, but if any of the program execution functions is enabled on your system (exec, system, shell_exec), you can use them to simply gzipthe file.

对许多人来说可能很明显,但是如果您的系统上启用了任何程序执行功能(execsystemshell_exec),您可以使用它们来简化gzip文件。

exec("gzip ".$filename);

N.B.:Be sure to properly sanitize the $filenamevariable before using it, especially if it comes from user input (but not only). It may be used to run arbitrary commands, for example by containing something like my-file.txt && anothercommand(or my-file.txt; anothercommand).

注意:$filename在使用变量之前一定要对其进行适当的清理,特别是如果它来自用户输入(但不仅如此)。它可用于运行任意命令,例如通过包含类似my-file.txt && anothercommand(或my-file.txt; anothercommand) 的内容。

回答by Anatoliy Melnikov

copy('file.txt', 'compress.zlib://' . 'file.txt.gz'); See documentation

copy('file.txt', 'compress.zlib://' .'file.txt.gz'); 查看文档

回答by Gerben

Here's an improved version. I got rid of all the nested if/else statements, resulting in lower cyclomatic complexity, there's better error handling through exceptions instead of keeping track of a boolean error state, some type hinting and I'm bailing out if the file has a gz extension already. It got a little longer in terms of lines of code, but it's much more readable.

这是一个改进的版本。我摆脱了所有嵌套的 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;
}

回答by ?àm

Compress folder for anyone needs

压缩文件夹以满足任何人的需要

function gzCompressFile($source, $level = 9)
{
    $tarFile = $source . '.tar';

    if (is_dir($source)) {
        $tar = new PharData($tarFile);
        $files = scandir($source);
        foreach ($files as $file) {
            if (is_file($source . '/' . $file)) {
                $tar->addFile($source . '/' . $file, $file);
            }
        }
    }

    $dest = $tarFile . '.gz';
    $mode = 'wb' . $level;
    $error = false;
    if ($fp_out = gzopen($dest, $mode)) {
        if ($fp_in = fopen($tarFile, 'rb')) {
            while (!feof($fp_in))
                gzwrite($fp_out, fread($fp_in, 1024 * 512));
            fclose($fp_in);
        } else {
            $error = true;
        }
        gzclose($fp_out);
        unlink($tarFile);
    } else {
        $error = true;
    }
    if ($error)
        return false;
    else
        return $dest;
}