如何使用 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
How do you create a .gz file using PHP?
提问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 (see comment to this answer about zip compression), or to compress.zip://
for zip compressioncompress.bzip2://
to bzip2 compression.
变化compress.zlib://
来(看到这个答案约ZIP压缩评论),或者compress.zip://
进行zip压缩compress.bzip2://
以压缩的bzip2。
回答by dtbarne
回答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 gzip
the file.
对许多人来说可能很明显,但是如果您的系统上启用了任何程序执行功能(exec
、system
、shell_exec
),您可以使用它们来简化gzip
文件。
exec("gzip ".$filename);
N.B.:Be sure to properly sanitize the $filename
variable 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;
}