views:

742

answers:

4

Hi,

I am trying to generate an archive on-the-fly in PHP and send it to the user immediately (without saving it). I figured that there would be no need to create a file on disk as the data I'm sending isn't persistent anyway, however, upon searching the web, I couldn't find out how. I also don't care about the file format.

So, the question is:

Is it possible to create and manipulate a file archive in memory within a php script without creating a tempfile along the way?

+1  A: 

what are you using to generate the archive? You might be able to use the stream php://temp or php://memory to read and write to/from the archive.

See http://php.net/manual/en/wrappers.php.php

Tom Haigh
At the moment, I'm using the php zip extension and writing a tempfile whenever I serve a download.I tried using the php://temp wrapper (figuring that it was superior to php://memory, as with large quantities of data, a tempfile IS a good idea, and hosts might allow its use even while restricting fs access.I ran into the problem that I had to close the zipfile, which appearantly freed everything in php://temp/ . (Reading from the zipfile before and after closing gave me 0 bytes.)Anyway, I don't care about the library I use, as long as it works. PHP-internal would be preferred, of course.
tkolar
A: 

Is there really a performance issue here, or does it just offend your sense of rightness? A lot of processes write temporary files and delete them, and often they never hit the disk due to caching.

A tempfile is automatically deleted when closed. That's it's nature.

There are only two ways I can think of to create a zip file in memory and serve it and both are probably more trouble than they are worth.

  • use a ram disk.
  • modify the ziparchive class to add a method that does everything the close() method does, except actually close the file. (Or add a leave-open parameter to close()).
    This might not even be possible depending on the underlying C libraries.
Lucky
+1  A: 

Regarding your comment that php://temp works for you except when you close it, try keeping it open, flushing the output, then rewind it back to 0 and read it.

Look here for more examples: http://us.php.net/manual/en/function.tmpfile.php

Also research output buffering and capturing: http://us.php.net/manual/en/function.ob-start.php

Chloe
A: 

you need to use ZipArchive::addFromString - if you use addFile() the file is not actually added until you go to close it. (Horrible bug imho, what if you are trying to move files into a zip and you delete them before you close the zip...) addFromString() adds it to the archive immediately

KinkyMUnkey