Here's a daft idea - not even good enough to call "half-baked" in that I don't know if it will work or how exactly to implement it.

Those "Your download should begin shortly" pages - where the page is displayed and then the file starts downloading. I think it's something to do with a multiplart http request (a multipart MIME type, the download page in the first part, and the file in the second part).

Have a third part which is also HTML, which, when it's loaded, makes a request to a "confirmation" script, including an appropriate ID for identifying the file. All going well, that confirmation signal will only be sent if the user's client actually received the third part of the response (and, therefore, the entirety of the second).

I'm not making much sense, am I? I've gotta sleep....

    Originally posted by swoolf
    even if I was deleting files every 24 hours. (That was my original thought - a scheduled task to wipe out the zips each night at 4 AM or something.)

    I wasn't talking about scheduling it. I was saying someone accesses your script. Before it builds their zip file it deletes any file that's been on the server more then x time. x is an epoch that you decide on. So if you're x is 24 hours then a file created at 3am on the 3rd would not be deleted before 3am on the 4th.

      simple soltion would be have the user tell you the file is done downlaoding. so click a Done button and then file get removed?

      or is that too simple and you wanted it all auto? with out any user action

      another solution would be to use a Status on files transcations, example most websites have STATUS (log of site useage) it tells you what files have been looked at when and how much KB sent. etc..
      maybe you can tap in that information and look at the IP of person downloading that file and look to see if that ZIP file sent XXmb out XXmb it would say on status page how much KB was sent.

      note i have not tryed any of the above solutions, just ideas

        These are all good ideas - thanks for your feedback, guys. If anyone else has ideas, please send them along.

        Right now I'm leaning toward running a scheduled task at 4AM or something to wipe out any zips that have been created that day. Maybe the simplest way is the best.

        I'll post the eventual solution this weekend when I get into the code.

        Thanks,

        Steve

          I was just thinking: assuming you recorded which files the users were selecting, and were creating archives on the fly initially, whether you actually need to retain the file for any particular length of time. Assuming you build the same files in the same order (with the same options) each time, the resulting zip file should be identical every time it's built. So if their download does fail partway through, and they request it again, you just build it and send it again. And if the file is identical each time, then it wouldn't matter if they only made a partial request for the bit they didn't receive (à la "wget -c").

          Of course, these subsequent downloads will be a bit slower, due to the need to recreate the zip each time, but since the majority of users will (hopefully) be requesting the file once only, that shouldn't be too grievous a hit.

            Can't you just compress some data using the Zlib extension and stream the gzip to the user? No need to create/destroy files then.

              The zip archive will have different files depending on what the user selects for download.

              I can't use the gzip, unfortunately. The end users are Windows 2000 non-techs who will not do well with anything other than the common Zip archive. Corporate mandate, I'm afraid...

              Steve

                What about WinXP? Can it handle gzips with the integrated WinZip?

                  Hmm not sure that Windows likes Gzips, at least right clicking a gzip doesn't produce an 'extract' option as with Winzips. Just noticed this on Sourceforge though 🙂

                    PKZip is a good package. Here's a simpler one, though. This is what I'm going with for now:

                    http://zend.com/codex.php?id=696&single=1

                    Speaking of compression, anyone have good ideas on how to circumvent script timeouts while a large (translation: 10-50MB or more) zip archive is assembled dynamically and compressed?

                    I was looking into output buffering, but I'm not sure if that will do the trick. I'd like to be able to offer the user a "Please wait while..." page while the script executes the creation of the zip in the background.

                    Thoughts on that?

                    Many thanks for all the great input,

                    Steve

                      Originally posted by swoolf
                      The zip archive will have different files depending on what the user selects for download.

                      Yes, which is why I noted that you'd need to record which files those are when they're selected. No doubt one user might ask for several downloads at different times, so you could provide a list of "previous downloads" (going back, say, a week), offering to zip up and provide the same collection of files that they asked for last time.

                        5 days later

                        Here's what worked for me (and works VERY well):

                        Using the script linked from zend.com (above), I am able to dynamically assemble the zip and stream it immediately to the client, so there is no longer even a need to keep track of any files written to disk.

                        For large files, you have to make sure you set php.ini's max memory usage settings appropriately.

                        Forcing the download was a little tricky, though. Netscape/Win has a little bug that does not append the corrent file extension when the zip is assembled dynamically, so you have to warn the user. Other than that, it works perfectly in all other browsers, including Mac browsers.

                        Use the following headers:

                        header('Pragma: public');
                        header('Expires: 0');
                        header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
                        header('Content-Type: application/zip'); // <- this could be octet-stream, as well
                        header('Content-Disposition: attachment; filename='.$filename.';');
                        header('Content-Transfer-Encoding: binary');

                        Hope that's of some use to you all. Thanks for all the great feedback.

                        Steve

                          Write a Reply...