Я хочу, чтобы gzip сжимал файл на моем сервере с помощью PHP. Есть ли у кого-нибудь пример, который будет вводить файл и выводить сжатый файл?
Как создать файл .gz с помощью PHP?
Ответ 1
Другие ответы здесь загружают весь файл в память во время сжатия, что приведет к ошибкам "из памяти" в больших файлах. Нижеприведенная функция должна быть более надежной в больших файлах при чтении и записи файлов в блоках размером 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;
}
Ответ 2
Этот код делает трюк
// 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);
Ответ 3
Кроме того, вы можете использовать php wrappers, сжатие. С минимальным изменением кода вы сможете переключаться между gzip, bzip2 или zip.
$input = "test.txt";
$output = $input.".gz";
file_put_contents("compress.zlib://$output", file_get_contents($input));
изменить compress.zlib://
на (см. комментарий к этому ответу о сжатии zip) или compress.zip://
для сжатия zipcompress.bzip2://
для сжатия bzip2.
Ответ 4
Простой один вкладыш с gzencode():
gzencode(file_get_contents($file_name));
Ответ 5
Если вы хотите просто разархивировать файл, это работает и не вызывает проблем с памятью:
$bytes = file_put_contents($destination, gzopen($gzip_path, r));
Ответ 6
Вероятно, это очевидно для многих, но если какая-либо из функций выполнения программы включена в вашей системе (exec
, system
, shell_exec
), вы можете использовать их для простого gzip
файла.
exec("gzip ".$filename);
NB: Обязательно должным образом очистите переменную $filename
перед ее использованием, особенно если она исходит от ввода пользователя (но не только). Он может использоваться для запуска произвольных команд, например, путем добавления чего-то вроде my-file.txt && anothercommand
(или my-file.txt; anothercommand
).
Ответ 7
copy ('file.txt', 'compress.zlib://'. 'file.txt.gz'); См. Документацию
Ответ 8
Здесь улучшенная версия. Я избавился от всех вложенных операторов if/else, что привело к снижению цикломатической сложности, улучшению обработки ошибок с помощью исключений вместо отслеживания состояния логической ошибки, подсказок некоторых типов, и я выручаю, если файл имеет расширение gz уже. С точки зрения строк кода он стал немного длиннее, но стал намного более читабельным.
/**
* Compress a file using gzip
*
* Rewritten from Simon East 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;
}