IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

Ecrire un gros zip fichier (Plus de 2Go)


Sujet :

Langage PHP

  1. #1
    Membre régulier
    Inscrit en
    Janvier 2007
    Messages
    248
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 248
    Points : 101
    Points
    101
    Par défaut Ecrire un gros zip fichier (Plus de 2Go)
    Hello tout le monde...
    Je suis en train de serrer donc je me résoud à demander de l'aide...

    J'essaye de générer un zip à partir de photos...

    J'ai testé avec la librairie Ziparchive de php http://us1.php.net/manual/fr/ziparch...fromstring.php
    méthodes addfile et addfromstring... ça change rien

    et là je suis en train de tester avec la zip.lib.php fournir avec phpmyadmin ...

    dans les deux cas j'ai un peu la même problématique.
    Il semblerait qu'au bout d'un certain nombre de fichier zippé (entre 320 et 350) le serveur arrête le script ...

    J'ai bien sur mis ce genre d'options
    set_time_limit(12000);
    ignore_user_abort(true);
    ini_set('memory_limit','20000M');

    j'ai un peu modifié la lib de phpmyadmin pour éviter de stocker les infos en mémoire et les enregistrer directement dans un fichier au fur et à mesure que le zip se génère... même combat :'(
    Erreur 500 au bout d'environ 20/30 secondes de traitement ...

    Alors mes questions sont ... est ce que fwrite as une limitation de taille pour écrire un fichier ? pareil pour ziparchive qui plante au moment de fermer le zip ($zip->close())

    faut il que je cherche ailleurs que sur un pb de mémoire ?
    J'envoie les fichiers un par un dans le zip.. ce sont des jpg de 3 à 10Mo en général ... donc pas énorme...

    bref je craque ...
    j'ai cherché dans les logs apache mais je n'ai rien trouvé comme commentaire sur l'erreur 500 ...

    Je suis complètement bloqué là :'(
    help

  2. #2
    Membre averti Avatar de demenvil
    Homme Profil pro
    Analyste développeur
    Inscrit en
    Avril 2009
    Messages
    195
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste développeur
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2009
    Messages : 195
    Points : 389
    Points
    389
    Par défaut
    Ton code ?
    Peut être pourrions nous l'améliorer

  3. #3
    Membre régulier
    Inscrit en
    Janvier 2007
    Messages
    248
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 248
    Points : 101
    Points
    101
    Par défaut
    Yes,
    La zip.lib.php un poil modifiée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    <?php
    /* vim: set expandtab sw=4 ts=4 sts=4: */
    /**
     * Zip file creation
     *
     * @package PhpMyAdmin
     */
     
    /**
     * Zip file creation class.
     * Makes zip files.
     *
     * @access  public
     * @package PhpMyAdmin
     * @see     Official ZIP file format: http://www.pkware.com/support/zip-app-note
     */
    class ZipFile
    {
        /**
         * Save the stream in file
         *
         * @var  boolean  $doWrite
         */
        var $OutFile      = '';
     
        /**
         * Whether to echo zip as it's built or return as string from -> file
         *
         * @var  boolean  $doWrite
         */
        var $doWrite      = false;
     
        /**
         * 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;
     
     
        /**
         * Sets member variable this -> doWrite to true
         * - Should be called immediately after class instantiantion
         * - If set to true, then ZIP archive are echo'ed to STDOUT as each
         *   file is added via this -> addfile(), and central directories are
         *   echoed to STDOUT on final call to this -> file().  Also,
         *   this -> file() returns an empty string so it is safe to issue a
         *   "echo $zipfile;" command
         *
         * @access public
         *
         * @return void
         */
        function setOutFile($file) {
            $this -> OutFile = $file;
            $this->fp = fopen($this->OutFile, 'a');
        }
        function setDoWrite()
        {
            $this -> doWrite = true;
        } // end of the 'setDoWrite()' method
     
        /**
         * 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 $unixtime 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  $data file contents
         * @param string  $name name of the file in the archive (may contains the path)
         * @param integer $time the current timestamp
         *
         * @access public
         *
         * @return void
         */
        function addFile($data, $name, $time = 0)
        {
            $name     = str_replace('\\', '/', $name);
     
            $dtime    = substr("00000000" . dechex($this->unix2DosTime($time)), -8);
            $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;
     
            // echo this entry on the fly, ...
            if ( $this -> doWrite) {
                echo $fr;
            } else if (trim($this->OutFile) != ''){
                 //on enregistre le flux
     
                  fwrite($this->fp, $fr);
     
            } else {                     // ... OR 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;
     
            return true;
        } // end of the 'addFile()' method
     
     
        /**
         * Echo central dir if ->doWrite==true, else build string to return
         *
         * @return string  if ->doWrite {empty string} else the ZIP file contents
         *
         * @access public
         */
        function file()
        {
            $ctrldir = implode('', $this -> ctrl_dir);
            $header = $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', $this -> old_offset) .       //offset to start of central dir
                "\x00\x00";                            //.zip file comment length
     
            if ( $this -> doWrite ) { // Send central directory & end ctrl dir to STDOUT
                echo $header;
                return "";            // Return empty string
            } else if (trim($this->OutFile) != ''){
                 //on enregistre le flux
     
                  fwrite($this->fp, $header);
                  fclose($this->fp);
            } else {                  // Return entire ZIP archive as string
                $data = implode('', $this -> datasec);
                return $data . $header;
            }
        } // end of the 'file()' method
     
    } // end of the 'ZipFile' class
    ?>
    Mon script un peu édulcoré mais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    set_time_limit(12000);
    ignore_user_abort(true);
    ini_set('memory_limit','20000M');
     
     
    $lignes = //toutes les lignes de ma bdd ou j'ai mes fichiers à ziper
     
    if (count($lignes)>0) {
     
    //	header("Content-Type: application/octet-stream");
    //	header("Content-Disposition: attachment; filename=zip_cmd_PROF_".$_GET['idCommande'].".zip");
     
    //	$zip = new zip();
    	$archive = 'tmp/test.zip' ;
    	if (is_file($archive)) {
    		unlink ($archive);
    	}
     
    	 // création d'un objet 'zipfile'
        if ( $zip = new zipfile()) {
     
     //   	 header('Content-Type: application/x-zip');
        // force le téléchargement
      // header('Content-Disposition: inline; filename=archive.zip');
     
        	//on flush direct le fichier
    	//	$zip->setDoWrite();
     
    		//pour ecrire le fichier direct
    		$zip->setOutFile($archive);
     
        	$cnt = 0 ;
        	foreach ($lignes as $l) {	
        		$cnt++;
     
        		if ($cnt <200000) {
      // ajout du fichier dans cet objet
     
        			$path = 'tirages/'.$l->fichierPhoto;
     
     
    		//réécriture du path selon la plateforme
        			$path = str_replace ("/", DIRECTORY_SEPARATOR, $path);
        			$path = str_replace ("\\", DIRECTORY_SEPARATOR, $path);
     
     
    	//	echo REALPATH.$path;echo '<br />';
     
     
     
     
        			if (is_file(REALPATH.$path)) {	
     
    //echo REALPATH.$path.'<br />';
     
        				if ($zip->addfile(  file_get_contents(REALPATH.$path),$_GET['idCommande'].'_'.$l->nomProduit.'/'.$l->quantite.'x_'.$l->fichierPhoto )=== true) {
     
        					log_txt('log_generationzip'.$_GET['idCommande'].'.log', $cnt.' - '.REALPATH.$path.' memory_get_usage='.(memory_get_usage()/1024/1024), false, '', true);
        				}
        			}
     
     
     
     
     
        			//$zip->addfile($content, $filename);
     
        		}
        	}
     
     
        	log_txt('log_generationzip'.$_GET['idCommande'].'.log', $cnt.' - fichiers ecrits memory_get_usage='.(memory_get_usage()/1024/1024), false, '', true);
     
        // fermeture de l'archive' Zip
        	$archive = $zip->file();
     
     
        	log_txt('log_generationzip'.$_GET['idCommande'].'.log', $cnt.' - zip ferme memory_get_usage='.(memory_get_usage()/1024/1024), false, '', true);
     
        	 // entêtes HTTP
     
        	//on écrit l'archive
    //  $fp = fopen('tmp/cmd_'.$_GET['idCommande'].'.zip', 'w');
     
    //  fwrite($fp, $archive);
    //	fclose($fp);
     
    echo 'fichier ecrit';
     
    die();
     
     //   header('Content-Type: application/x-zip');
        // force le téléchargement
     //   header('Content-Disposition: inline; filename=archive.zip');
     
        // envoi du fichier au navigateur
     //   echo $archive;
     
        }

Discussions similaires

  1. Décompresser des fichiers ZIP de plus de 35 Mo
    Par Général03 dans le forum Langage
    Réponses: 3
    Dernier message: 15/03/2010, 10h03
  2. Réponses: 4
    Dernier message: 30/12/2008, 11h30
  3. Ecrire un gros fichier XML
    Par foubou dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 24/04/2008, 22h08
  4. Réponses: 4
    Dernier message: 13/11/2007, 10h10
  5. TFileStream et les fichiers de plus de 2Go
    Par naikon dans le forum C++Builder
    Réponses: 3
    Dernier message: 29/06/2004, 16h11

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo