PHP|Débutant :: Forums

Advertisement

Besoin d'aide ? N'hésitez pas, mais respectez les règles

Vous n'êtes pas identifié(e).

#1 14-03-2011 17:34:40

loydbrien
Membre
Inscription : 14-03-2011
Messages : 3

Php Zip et dossier racine

Bonjour à tous,

Je me permets de poster ici car après avoir décortiqué toutes les possibilités de mon code, je bloque sur un point.

Il s'agit au juste d'une fonction pour zipper, elle fonctionne à merveille ce n'est pas le soucis, elle compresse même plusieurs dossiers et fichiers ensemble.

Là où est mon soucis c'est que lorsque je lance le script et qu'il compresse, il créer un dossier général au lieu de me zipper tous mes dossiers et fichiers à la racine tels quels.

Ce que je veux c'est que lorsque je décompresse mon .zip, l'extraction soit de tous les fichiers et non d'un dossier général qui les regroupe tous qui a été créé lors de la compression.

Voici la classe pour zipper (zip.lib.php) :

<?php
class zipfile
{
    /**
     * Array to store compressed data
     *
     * @var  array    $datasec
     */
    var $datasec      = array();

    /**
     * Central directory
     *
     * @var  array    $ctrl_dir
     */
    var $ctrl_dir     = array();

    /**
     * End of central directory record
     *
     * @var  string   $eof_ctrl_dir
     */
    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";

    /**
     * Last offset position
     *
     * @var  integer  $old_offset
     */
    var $old_offset   = 0;


    /**
     * Converts an Unix timestamp to a four byte DOS date and time format (date
     * in high two bytes, time in low two bytes allowing magnitude comparison).
     *
     * @param  integer  the current Unix timestamp
     *
     * @return integer  the current date in a four byte DOS format
     *
     * @access private
     */
    function unix2DosTime($unixtime = 0) {
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);

        if ($timearray['year'] < 1980) {
            $timearray['year']    = 1980;
            $timearray['mon']     = 1;
            $timearray['mday']    = 1;
            $timearray['hours']   = 0;
            $timearray['minutes'] = 0;
            $timearray['seconds'] = 0;
        } // end if

        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) |
                ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
    } // end of the 'unix2DosTime()' method


    /**
     * Adds "file" to archive
     *
     * @param  string   file contents
     * @param  string   name of the file in the archive (may contains the path)
     * @param  integer  the current timestamp
     *
     * @access public
     */
    function addFile($data, $name, $time = 0)
    {
        $name     = str_replace('\\', '/', $name);

        $dtime    = dechex($this->unix2DosTime($time));
        $hexdtime = '\x' . $dtime[6] . $dtime[7]
                  . '\x' . $dtime[4] . $dtime[5]
                  . '\x' . $dtime[2] . $dtime[3]
                  . '\x' . $dtime[0] . $dtime[1];
        eval('$hexdtime = "' . $hexdtime . '";');

        $fr   = "\x50\x4b\x03\x04";
        $fr   .= "\x14\x00";            // ver needed to extract
        $fr   .= "\x00\x00";            // gen purpose bit flag
        $fr   .= "\x08\x00";            // compression method
        $fr   .= $hexdtime;             // last mod time and date

        // "local file header" segment
        $unc_len = strlen($data);
        $crc     = crc32($data);
        $zdata   = gzcompress($data);
        $zdata   = substr(substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
        $c_len   = strlen($zdata);
        $fr      .= pack('V', $crc);             // crc32
        $fr      .= pack('V', $c_len);           // compressed filesize
        $fr      .= pack('V', $unc_len);         // uncompressed filesize
        $fr      .= pack('v', strlen($name));    // length of filename
        $fr      .= pack('v', 0);                // extra field length
        $fr      .= $name;

        // "file data" segment
        $fr .= $zdata;

        // "data descriptor" segment (optional but necessary if archive is not
        // served as file)
        // nijel(2004-10-19): this seems not to be needed at all and causes
        // problems in some cases (bug #1037737)
        //$fr .= pack('V', $crc);                 // crc32
        //$fr .= pack('V', $c_len);               // compressed filesize
        //$fr .= pack('V', $unc_len);             // uncompressed filesize

        // add this entry to array
        $this -> datasec[] = $fr;

        // now add to central directory record
        $cdrec = "\x50\x4b\x01\x02";
        $cdrec .= "\x00\x00";                // version made by
        $cdrec .= "\x14\x00";                // version needed to extract
        $cdrec .= "\x00\x00";                // gen purpose bit flag
        $cdrec .= "\x08\x00";                // compression method
        $cdrec .= $hexdtime;                 // last mod time & date
        $cdrec .= pack('V', $crc);           // crc32
        $cdrec .= pack('V', $c_len);         // compressed filesize
        $cdrec .= pack('V', $unc_len);       // uncompressed filesize
        $cdrec .= pack('v', strlen($name) ); // length of filename
        $cdrec .= pack('v', 0 );             // extra field length
        $cdrec .= pack('v', 0 );             // file comment length
        $cdrec .= pack('v', 0 );             // disk number start
        $cdrec .= pack('v', 0 );             // internal file attributes
        $cdrec .= pack('V', 32 );            // external file attributes - 'archive' bit set

        $cdrec .= pack('V', $this -> old_offset ); // relative offset of local header
        $this -> old_offset += strlen($fr);

        $cdrec .= $name;

        // optional extra field, file comment goes here
        // save to central directory
        $this -> ctrl_dir[] = $cdrec;
    } // end of the 'addFile()' method


    /**
     * Dumps out file
     *
     * @return  string  the zipped file
     *
     * @access public
     */
    function file()
    {
        $data    = implode('', $this -> datasec);
        $ctrldir = implode('', $this -> ctrl_dir);

        return
            $data .
            $ctrldir .
            $this -> eof_ctrl_dir .
            pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries "on this disk"
            pack('v', sizeof($this -> ctrl_dir)) .  // total # of entries overall
            pack('V', strlen($ctrldir)) .           // size of central dir
            pack('V', strlen($data)) .              // offset to start of central dir
            "\x00\x00";                             // .zip file comment length
    } // end of the 'file()' method

} // end of the 'zipfile' class
?>

Et donc voici la partie à exécuter :

<?php
require('zip.lib.php');

$zip = new zipfile();

$filename = array('dossier/fichier1','dossier/fichier2','dossier/fichier3');

$a = 0;
while(count($filename)>$a)
{
$fp = fopen($filename[$a],'r');
$contenu = fread($fp, filesize($filename[$a]));

fclose($fp);

$zip->addfile($contenu, $filename[$a]);
$a++;
}

$archive = $zip->file();

header('Content-Type: application/x-zip');
header('Content-Disposition: inline; filename=archive.zip');

echo $archive;
?>

Donc dans ce cas par exemple il va m'appeler l'archive archive.zip par de soucis mais lorsque je la décompresse, je n'ai pas mes fichiers immédiatement mais d'abord un dossier principal qui s'appellera soit archive soit le nom du dossier maitre compressé.

Si quelqu'un à la solution pour que ça compresse tel quel sans dossier principal, merci d'avance car j'ai eu beau chercher, je crois qu'en fin de journée je ne vois plus rien.

Merci encore d'avance.

Loyd

Hors ligne

#2 14-03-2011 18:20:07

mcAllan
Mowdérateur
Lieu : Châteaurenard en Provence
Inscription : 08-05-2009
Messages : 269

Re : Php Zip et dossier racine

Salut,

Je ne voie pas trop de solution, il me semble que c'est le fonctionnement normal de l'archivage ZIP...
Si tu fait l'extraction de l'archive en PHP, tu peux coder le fonctionnement attendu.

A+


Promotion de PPOO : Programmation Propre Orientée Objet !!
Recommande AAO : Apéritif Avec Olives...
Glop, glop

Hors ligne

#3 14-03-2011 18:21:48

loydbrien
Membre
Inscription : 14-03-2011
Messages : 3

Re : Php Zip et dossier racine

mcAllan a écrit :

Salut,

Je ne voie pas trop de solution, il me semble que c'est le fonctionnement normal de l'archivage ZIP...
Si tu fait l'extraction de l'archive en PHP, tu peux coder le fonctionnement attendu.

A+

C'est à dire l'extraction de l'archive ?

Mon but final n'est pas d'arriver à un zip initialement mais à un .xpi d'où pourquoi mes fichiers doivent être à la racine car c'est une extension firefox que je souhaite faire et si le fichier install n'est pas à la racine ça ne fonctionne pas.

A te lire

Hors ligne

#4 14-03-2011 18:56:10

mcAllan
Mowdérateur
Lieu : Châteaurenard en Provence
Inscription : 08-05-2009
Messages : 269

Re : Php Zip et dossier racine

loydbrien a écrit :

...lorsque je décompresse mon .zip...

C'est dans ce script là qu'il faut extraire au bon endroit (si c'est un script).
En utilisant la classe ZipArchive par exemple.

A+


Promotion de PPOO : Programmation Propre Orientée Objet !!
Recommande AAO : Apéritif Avec Olives...
Glop, glop

Hors ligne

#5 14-03-2011 18:57:28

loydbrien
Membre
Inscription : 14-03-2011
Messages : 3

Re : Php Zip et dossier racine

Mon but étant de zipper en racine tel quel mais visiblement ça ne fonctionne pas.

Je vais tester du côté de ZipArchive ...

Si certains ont une idée je prends.

Bonne soirée

Hors ligne

#6 12-07-2011 14:08:51

sabat
Membre
Inscription : 12-07-2011
Messages : 1

Re : Php Zip et dossier racine

Bonjour, je me permet de revenir sur le sujet car j'ai aussi pas mal galéré et j'ai la solution qui est toute bete !

Voila mon code pour ajouter plusieurs fichiers a la RACINE de l'archive

require( "lib/zip.lib.php" ) ; // librairie ZIP
$zip = new zipfile () ; //on crée une instance zip

 //le tableau qui contient les chemin de fichiers entiers pour pouvoir les copier dans l'archive
$files = array('MonRepertoire/MonsousRepertoire/monFichier.txt','MonRepertoire/MonsousRepertoire/monFichier2.txt');    

 //le tableau qui ne contient que les nom des fichiers pour qu'ils se mettent directement a la racine
$name=array('monFichier.txt','monFichier2.txt');  


while ( count( $files ) > $i )   {

    $fo = fopen($files[$i],'r') ; //on ouvre le fichier
    $contenu = fread($fo, filesize($files[$i])) ; //on enregistre le contenu
    fclose($fo) ; //on ferme fichier

    $zip->addfile($contenu, $name[$i]) ; //on ajoute le fichier
    $i++; //on incrémente i

    }

    $archive = $zip->file() ; // on associe l'archive

    // on enregistre l'archive dans un fichier
    $open = fopen("monRepertoire/fichiers.zip" , "wb");
    fwrite($open, $archive);
    fclose($open);

Ainsi les fichiers sont bien copier a la racine puisque le nom des fichiers ne contient plus le chemin entier.

Voila j'espère que ça va en aider quelques uns.

Dernière modification par sabat (12-07-2011 14:10:15)

Hors ligne

Pied de page des forums