Ich möchte eine Datei auf meinem Server mit PHP komprimieren. Hat jemand ein Beispiel, das eine Datei eingeben und eine komprimierte Datei ausgeben würde?
Bei den anderen Antworten wird die gesamte Datei während der Komprimierung in den Speicher geladen. Dies führt bei großen Dateien zu ' out of memory ' Fehlern. Die folgende Funktion sollte bei großen Dateien zuverlässiger sein, da sie Dateien in 512-KB-Chunks liest und schreibt.
/**
* 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;
}
Dieser Code macht den 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);
Sie können auch php's Wrapper , die Kompression verwenden. Mit einer minimalen Änderung des Codes können Sie zwischen gzip, bzip2 oder zip wechseln.
$input = "test.txt";
$output = $input.".gz";
file_put_contents("compress.zlib://$output", file_get_contents($input));
compress.zlib://
in ändern (siehe Kommentar zu dieser Antwort zur Zip-Komprimierung) oder zu compress.Zip://
für die Zip-Komprimierungcompress.bzip2://
zur bzip2-Komprimierung.
Einfacher Liner mit gzencode () :
gzencode(file_get_contents($file_name));
Wenn Sie nur eine Datei entpacken möchten, funktioniert dies und verursacht keine Probleme mit dem Speicher:
$bytes = file_put_contents($destination, gzopen($gzip_path, r));
Es ist wahrscheinlich für viele offensichtlich, aber wenn eine der Programmausführungsfunktionen auf Ihrem System aktiviert ist (exec
, system
, Shell_exec
), können Sie diese einfach dazu verwenden, gzip
die Datei zu verwenden.
exec("gzip ".$filename);
N.B .: Stellen Sie sicher, dass Sie die $filename
-Variable vor der Verwendung desinfizieren, insbesondere wenn sie von Benutzereingaben stammt (aber nicht nur). Es kann verwendet werden, um beliebige Befehle auszuführen, zum Beispiel indem es etwas wie my-file.txt && anothercommand
(oder my-file.txt; anothercommand
) enthält.
copy ('file.txt', 'compress.zlib: //'. 'file.txt.gz'); Siehe documentation
Hier ist eine verbesserte Version. Ich habe alle verschachtelten if/else-Anweisungen entfernt, was zu einer geringeren zyklomatischen Komplexität geführt hat. Es gibt eine bessere Fehlerbehandlung durch Ausnahmen, anstatt einen booleschen Fehlerzustand, einige Typhinweise zu verfolgen, und ich bin am Ausstieg, wenn die Datei die Erweiterung gz hat bereits. In Bezug auf Codezeilen ist es etwas länger geworden, aber es ist viel besser lesbar.
/**
* 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;
}