Page 1 sur 2

zipper un répertoire

Posté : 10 sept. 2006, 11:13
par jojolapine
Bonjour à tous,
J'ai cherché un peu partout, sur le forum, sur php.net, et je ne vois pas (je suis peut-être "bigleu"?) ce que je souhaite.
En fait je veu pour voir générer à la volée un zip d'un répertoire, et tout ce que j'ai trouvé jusque là, c'est des compressions fichier par fichier...
Je suis un peu perdu... :cry:
Si vous avez une suggestion?
Existe-t-il une librairie qui permette de faire:
$zipdir=zipdir('monrépertoire');
et que tout soit bien mit dans l'archive, ou dois-je passer par les fonctions de listage de répertoire (sachant que là je ne connais pas à priori le nombre de sous-dossiers et le nombre "d'étages"...) et ensuite faire de la compression fichier par fichier.
Merci d'avance!

Posté : 10 sept. 2006, 12:29
par HD

Posté : 10 sept. 2006, 13:10
par jojolapine
lien interessant mais je ne suis pas inscrit et ne peut donc pas télécharger les sources

Posté : 10 sept. 2006, 13:29
par HD
mais tu peux t'inscrire :?

Posté : 10 sept. 2006, 13:59
par jojolapine
:oops: c'est bon c'est fait :roll:
Je regarde si ça marche!
merci

Posté : 10 sept. 2006, 14:29
par jojolapine
euh...
par contre j'arrive pas à le faire marcher ... :(
Quelqu'un l'a déja utilisé cette librairie?
Alors voilà le message d'erreur que j'ai:

Code : Tout sélectionner

Erreur de compression : PCLZIP_ERR_READ_OPEN_FAIL (-2) : Unable to open archive './archives/dl2006-09-10_121209093636.zip' in wb mode
c'est visiblement un problème avec pclzip, mais j'ai mit tout le répertoire en 777, donc bon je sais pas trop quoi faire... une idée?

Posté : 10 sept. 2006, 16:39
par naholyr
Je pense que c'est un problème de droits d'écriture sur le dossier dans lequel tu veux créer le dossier. Essaie de faire un chmod 777 sur le dossier.
Edit : ah oui tu l'as déjà fait, as-tu essayé de créer un fichier texte bidon dans ce dossier à l'aide du même script mais sans pclzip (pour test fopen() en mode 'wb') ?

Note : plutôt que d'utiliser la surcouche citée plus haut, à ta place j'utiliserais directement PCLZip :
<?php
  include('pclzip.lib.php');
  $archive = new PclZip('archive.zip');
  $archive->create('dossier/');
?>

Posté : 10 sept. 2006, 16:59
par jojolapine
Euh j'ai peur de pas trop comprendre...?
Si je fait ce que tu me dits d'utiliser juste pcl, ça ne me cré rien du tout, n'affiche aucune erreur ...?
Pour tant c'est vrai qu'en relisant la doc pcl, ça devrait pouvoir marcher...

edit: autant pour moi, c'étaitune erreur de chemin relatif, il n'arrivai pas à trouver mon répertoire, par contre, il n'arrive toujours pas à ouvrir mon fichier .zip comme la première erreur citée plus haut

Posté : 10 sept. 2006, 17:02
par JazzFinder
Un script que j’avais dans mes archives. Je ne peux te garantir la compatibilité avec des versions récentes de PHP.

Très pratique pour produire des zip à la volée de répertoires, et les consulter offline.

Dans ce cas, tu peux donner un lien .php à ton fichier zippé. En cliquant dessus, le «zippage» du répertoire se fait à la volée. Très pratique aussi quand le contenu de ce répertoire change, mais qu’on désire avoir un zip toujours actuel. Dans ce cas, pas besoin d’offrir un fichier .zip, qui nécessiterait une certaine maintenance, mais, comme je le disais, donner un zip dynamique avec une extension .php

Pour que ça marche, ce nouveau fichier .php aura le même nom que celui du répertoire zippé, et doit résider dans le même répertoire (source).

Supposons que ton répertoire s'appelle dir, ton lien doit être qqchose du genre: www.ton_site.com/.../.../dir.php
<?php
// Ce script zippe un répertoire et son contenu à la volée et le rend disponible

// Obtenir le nom de ce fichier php, sans extension, qui est également le nom du répertoire à zipper
$filename_no_ext=str_replace(".php","",basename($SCRIPT_NAME));

// On livre le fichier zip
header("Content-Type: archive/zip");

// Nom sous lequel le navigateur doit sauvegarder le fichier zip
header("Content-Disposition: attachment; filename=$filename_no_ext".".zip");

// Obtenir un nom temportaire (tmp) pour le .zip
$tmp_zip = tempnam ("tmp", "tempname") . ".zip";

// Zipper tout dans le fichier tmp_zip
`zip -r $tmp_zip $filename_no_ext`;
 
// Calculer la taille du zip. Ceci est nécessaire pour la barre de progression du navigateur
$filesize = filesize($tmp_zip);
header("Content-Length: $filesize");

// Livrer le fichier zip
$fp = fopen("$tmp_zip","r");
echo fpassthru($fp);

// clean up the tmp zip file
`rm $tmp_zip `;
?>
Notes:
- Le fichier .php (et donc le nom du répertoire) ne doit pas contenir de caractères spéciaux, ni des espaces (des blancs).
- Attention aux headers. Pas d'espace avant leur envoi.

Posté : 10 sept. 2006, 17:04
par jojolapine
merci jazzfinder, mais je ne souhaite pas utiliser de ligne de commandes :wink:

Posté : 10 sept. 2006, 18:46
par JazzFinder
merci jazzfinder, mais je ne souhaite pas utiliser de ligne de commandes :wink:
Non, ce n'est pas de la ligne de commande, c'est du PHP uniquement.

De toute façon, quelque chose cloche dans le code que je t'ai donné. J'ai fait plusieurs tests, et le zip obtenu ne dépasse guère les 1 Kb, et est impossible à consulter. Désolé.

Quelqu'un d'expérimenté sur ce forum peut certainement mieux te conseiller, ou encore essayer de débuguer ce code.

Posté : 10 sept. 2006, 18:48
par Ripat
Et pourquoi pas utiliser la librairie zlib?
http://php.net/manual/fr/ref.zlib.php

Edit:

Je ne l'avais jamais testée mais cette librairie marche très bien. La partie compression a été écrite par un Français, Jean-Loup Gailly et est identique à l'utilitaire GNU gzip. Un fichier compressé par php zlib peut très bien être décompressé par Linux gunzip et inversément.

Pour l'exemple, voici une petite fonction trouvée sur le net et que j'ai adaptée.
// fonction
function gzip($src, $dest, $overwrite = false){
  $level = 9;   // niveau de compression. 9 = max.
  $dest = $dest.basename($src).".gz";
  if(file_exists($src)){
    $src_handle = fopen($src, "r");
    if(!file_exists($dest) || $overwrite){
      if(! $dest_handle = gzopen($dest, "w$level")) return false;
      while(!feof($src_handle)){
        $chunk = fread($src_handle, 2048);
        gzwrite($dest_handle, $chunk);
      }
      fclose ($src_handle);
      gzclose($dest_handle);
      return true;
    } else {
      echo "$dest existe déjà";
    }
  } else {
    echo "$src n'existe pas";
  }
  return false;
}

// fichier à compresser
$src       = '/home/jeanluc/scripts/test/test2.txt';

// nom répertoire de destination (attention aux droits!). Laisser vide pour répertoire courant
$dest      = '';

// écraser le fichier de destination s'il existe? (false par défaut)
$overwrite = true;

// appel à la fonction (affiche 1 si ok)
echo (int) gzip($src, $dest, $overwrite);

Posté : 11 sept. 2006, 11:21
par jojolapine
Elle marche très bien sauf dans mon cas, ou je cherche à zipper un répertoire dont la taille et l'arborescenc m'est inconnu...!
Mais je croit que je vais devoir coder une fonction récursive pour le faire avec des fonction de zippage fichier par fichier... :(

Posté : 12 sept. 2006, 01:46
par zigz4g
Salut.
Je voudrais juste rajouter un petit commentaire sur les droits des répertoires Linux/Unix, il est bon de faire des tests avec les droits en 777 pour savoir d'ou peut provenir les problèmes mais il sera très bon de les remettre ensuite dans une bonne configuration.
Autre petit détail, tu parles des droits l'accès aux fichiers mais tu nous a pas dis si c'était bien Apache ou autre serveur qui peu y accéder. Effectivement avec un 777 sur un répertoire tu peux faire beaucoup de chose mais est-que tous les fichiers sont en 777 ??? Regarde le possesseur et le groupe de tes fichiers peut etre en plus.

Le problème des répertoires volumineux peut aussi te poser problème sur le temps de traitement de ton script. Il faudra peut etre voir par passer par un script lancer en ligne de commande.
Je recommanderais plus de faire un joli script bash et de le lancer avec un crontab. Ensuite il ne reste plus qu'a les envoyer ou les proposer aux téléchargement.

Posté : 12 sept. 2006, 12:14
par Ripat
Et si tu ne veux pas réinventer la roue:
http://pear.php.net/package/File_Archive

Tutorial sur:
http://poocl.la-grotte.org/

:wink: