Je voudrais gzip compresser un fichier sur mon serveur en utilisant PHP. Quelqu'un a-t-il un exemple permettant d'entrer un fichier et de générer un fichier compressé?
Les autres réponses ici chargent le fichier entier en mémoire pendant la compression, ce qui provoquera des erreurs ' manque de mémoire ' sur les gros fichiers. La fonction ci-dessous devrait être plus fiable pour les fichiers volumineux, car elle lit et écrit des fichiers en morceaux de 512 Ko.
/**
* 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;
}
Ce code fait l'affaire
// 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);
En outre, vous pouvez utiliser les php wrappers , ceux ceux de compression . Avec un changement minime du code, vous pourrez basculer entre gzip, bzip2 ou Zip.
$input = "test.txt";
$output = $input.".gz";
file_put_contents("compress.zlib://$output", file_get_contents($input));
remplacez compress.zlib://
par (voir le commentaire à cette réponse sur la compression Zip), ou compress.Zip://
pour la compression Zipcompress.bzip2://
à la compression bzip2.
Simple liner avec gzencode () :
gzencode(file_get_contents($file_name));
Si vous cherchez à décompresser un fichier, cela fonctionne et ne cause pas de problèmes de mémoire:
$bytes = file_put_contents($destination, gzopen($gzip_path, r));
C'est probablement évident pour beaucoup, mais si l'une des fonctions d'exécution du programme est activée sur votre système (exec
, system
, Shell_exec
), vous pouvez les utiliser simplement pour gzip
le fichier.
exec("gzip ".$filename);
N.B .: Assurez-vous de bien nettoyer la variable $filename
avant de l’utiliser, en particulier si elle provient d’une entrée utilisateur (mais pas seulement). Il peut être utilisé pour exécuter des commandes arbitraires, par exemple en contenant quelque chose comme my-file.txt && anothercommand
(ou my-file.txt; anothercommand
).
copy ('fichier.txt', 'compress.zlib: //'. 'fichier.txt.gz'); Voir documentation
Voici une version améliorée. Je me suis débarrassé de toutes les instructions if/else imbriquées, ce qui a réduit la complexité cyclomatique. Il existe une meilleure gestion des erreurs grâce aux exceptions au lieu de garder la trace d'un état d'erreur booléenne, d'un indice de type et si le fichier a une extension gz déjà. Cela a pris un peu plus de temps en termes de lignes de code, mais c'est beaucoup plus lisible.
/**
* 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;
}