Menu

#1295 (ok 3.5) stream .zip output on the fly

Next_minor_version
fixed
nobody
1
2014-08-14
2011-04-03
No

I get this error

Allowed memory size of [N] bytes exhausted

when using

[phpmyadmin/phpmyadmin] / libraries / zip.lib.php

to generate large .zip files in CGI scripts. Most solutions on the web suggest boosting memory_limit in php.ini (apache).

The diff output below (I'll add a patch shortly) provides a way to stream .zip files direct to stdout (it should probably be changed to use an arbitrary stream). These changes also contain a fix for a bug in the file timestamps (dechex() does not produce the necessary 8-character strings for older timestamps).

All that is needed to use this option is to add a call to ->setDoWrite() immediately after the instantiation of the zipfile class e.g.

require zip.lib.php
[...]
$zf = new zipfile;
$zf->setDoWrite();
for ( $filnames as $fn) { $zf->addFile( file_get_contents($fn), basename($fn)); }
echo $zf->file(); // ->file() returns empty string after ->setDoWrite()

Diff output follows; modified zip.lib.php, called zipstream.lib.php, is attached.

27a28,34
> * Whether to write zip file via echo in one pass and have
> * have -> file return an empty string, or to save all info
> * and have -> file() return entire zip file in a string
> */
> var $doWrite = false;
>
> /**
55a63,66
> function setDoWrite() {
> $this -> doWrite = true;
> }
>
96c107
< $dtime = dechex($this->unix2DosTime($time));
---
> $dtime = substr( "00000000" . dechex($this->unix2DosTime($time)), -8);
133,134c144,149
< // add this entry to array
< $this -> datasec[] = $fr;
---
> // write this entry on the fly, ...
> if ( $this -> doWrite) {
> echo $fr;
> } else { // ... OR add this entry to array
> $this -> datasec[] = $fr;
> }
165c180
< * Dumps out file
---
> * Dumps out file to stdout if ->doWrite==true, else to return value as string
167c182,183
< * @return string the zipped file
---
> * @return string if ->doWrite ==false: the zipped file
> * else the empty string
173,184c189,212
< $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
---
> if ( $this -> doWrite ) {
> $ctrldir = implode('', $this -> ctrl_dir);
> echo $ctrldir;
> echo $this -> eof_ctrl_dir;
> echo pack('v', sizeof($this -> ctrl_dir)); // total # of entries "on this disk"
> echo pack('v', sizeof($this -> ctrl_dir)); // total # of entries overall
> echo pack('V', strlen($ctrldir)); // size of central dir
> echo pack('V', $this -> old_offset); // offset to start of central dir
> echo "\x00\x00"; // .zip file comment length
> return "";
> } else {
> $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
> }

Discussion

  • Brian Carcich

    Brian Carcich - 2011-04-03

    update to zip.lib.php

     
  • Brian Carcich

    Brian Carcich - 2011-04-03
    • priority: 5 --> 1
     
  • Michal Čihař

    Michal Čihař - 2011-05-17

    This requested feature was implemented in the repository and will be part of a future release; thanks for suggesting.

     
  • Michal Čihař

    Michal Čihař - 2011-05-17
    • summary: stream .zip output on the fly, reduces memory requirement --> (ok 3.5) stream .zip output on the fly
    • status: open --> open-fixed
     
  • Marc Delisle

    Marc Delisle - 2012-04-07
    • status: open-fixed --> closed-fixed
     
  • Michal Čihař

    Michal Čihař - 2013-06-11
    • Status: closed-fixed --> fixed
     
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.