cags Posted November 25, 2009 Share Posted November 25, 2009 I feel abit dumb asking this, but I've never really worked much with files. I have a site that I'm currently in the process of adding downloads to. The theory is the user will go to the site, click a link for a download that will have a URL of something along the lines of... http://www.domain.com/downloads/21/name-of-file This will be forwarded with mod_rewrite to something along the lines of... http://www.domain.com/downloads/?fileid=21&filename=name-of-file The theory is the script will check the file exists, assuming it does update the download count then send the file to the user. Now the mod_rewrite, querying the database and updating the database I can do no problem. The problem is I'm not entirely sure how to 'initialise' the download to the user. I'm guessing I'm going to need to use Content-Type headers(?), just not sure how to 'include' the actual file for download. A page should then be displayed saying thanks for download (I say 'then' but I'm assuming this will be output before sending the file). The files will mainly be .exe or .zip and may be upto 10Mb or so if that makes a difference. I've tried searching, but apparently I'm not sure what to look for because it doesn't seem an uncommon thing, yet I can't find a solution :-\ I'm sure all I need is a function name, but if you don't know it, you don't know it. Quote Link to comment Share on other sites More sharing options...
cags Posted November 25, 2009 Author Share Posted November 25, 2009 Well I think I answered my own problem. I discovered readfile, which seems to be just the ticket. Running a few small tests though I'm having a bit of trouble with the example in the manual... $file = 'myfile.zip'; if (file_exists($file)) { header('Content-Description: File Transfer'); header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename='.basename($file)); header('Content-Transfer-Encoding: binary'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header('Content-Length: ' . filesize($file)); ob_clean(); flush(); readfile($file); exit; } The download prompt appears but whether I save it then open it or open it directly, WinRAR reports "Unexpected end of archive". The file appears to be the same size (10.5Kb). I tried changing the Content-Type header to application/zip, but it made no difference. I'm not particularly familiar with most of the other headers, but I don't see anything I feel should cause problems. Any suggestions? Quote Link to comment Share on other sites More sharing options...
cags Posted November 25, 2009 Author Share Posted November 25, 2009 Curiously it worked with Chrome, but not IE, Firefox or Safari. Regardless, I've solved the problem by calling ob_start before sending the headers. None of the examples in the documentation for readfile, flush or ob_clean seem to indicate this should be required. Am I missing something? Is it a bug with my version of PHP (5.2.9)? Some kind of setting?! Or is it just an omission in the documentation?! Any thoughts? Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted November 25, 2009 Share Posted November 25, 2009 If you open, using a programming editor, the downloaded files that failed, you will probably find some php error messages, particularly due to calling ob_clean() when there is no output buffer in use. You don't need any of these lines of code - ob_clean(); flush(); exit; The filename portion of the 'Content-Disposition: attachment; filename="..." header should be enclosed in quotes to make all browsers happy. Quote Link to comment Share on other sites More sharing options...
cags Posted November 25, 2009 Author Share Posted November 25, 2009 Ok, thanks for the information. Your right, there was an error message at the start of the file. The code I was using came straight from the PHP manual, it's odd they have an example that doesn't work, perhaps I should report it. I need to display information back to the user, should I attempt this using a download-manager page and a download page, one file to track the download and the other to actually act as the file/download? Otherwise I'm obviously going to get buffer issues. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.