I have a script that looks up a file in a mysql database, sends out some headers, names the file something human-readable, and then delivers it the the user.
It was working for about six months (for thousands of users), until about 6 hours ago. Now, Windows 7 users now get an error that says "Windows can not open the folder. The Compressed (zipped) Folder: '...filename.zip' is invalid." This happens regardless of browser used to download. Linux users, etc., can open the delivered files just fine, and so can Win7 users if they have, say, WinRAR. Only Windows Explorer can't open them.
Here's where it gets really weird... if I make a new copy of my script and remove the various includes that look up the files and decide what to name it, it will download and open just fine... the resulting files from both scripts are identically sized and the resulting name is identical. [Hardcoding the new name into the original script does not help. I kind of thought it might be an encoding issue in the name.] I have tried with a few different zip files with different contents created on different machines by different methods.
The script checks for headers_sent(), file_exists(), and is_readable().
apache_setenv('no-gzip', '1'); was added to the scripts (with no effect) following the only semi-relevant info I could find here or elsewhere on the internet.
Clearly, something in the includes is breaking things somehow, but I haven't any idea what to look for... Ideas? (There are about 300 lines of code in the includes... basically, it's an abstract class for database access, a concrete version of that class for the files and all of their cms info, associated images for the site, etc.)
On a whim, I added "ob_clean(); right before the readfile($file);... it fixed it. So my question now, is: why? Error reporting is off in all of the files. What else could send output but not headers? And why the "sudden" change in behaivor?
Major Issue
Have seen this error before and took me time to identify the issues because sometimes its says Header already sent and sometimes it does not.
Here is what i found out :
ob_clean works when you discards the contents of the output buffer but if you use ob_ get_ contents before calling ob_clean you would would see the content causing the error
To output this information make sure you use var_dump
Some other errors
If there is a space (" " or " \n" or "\t") after calling the ?> tag i often get errors that can only be resolved by ob_clean
Open your script look for script that has more lines of empty space after the ?> close tag
Conclusion
I think there is an empty space included in your script you are not seeing and when you copy it .. you are not copying the script but not the spaces that is why it works elsewhere
Take out the ob_clean(); and open a damaged file in Wordpad or some hex viewer. The slightest traces of non-binary output (that includes spaces, commas, E_NOTICEs, periods, dust, bird poop etc) will cripple the ZIP.
At best you'll probably just find some E_NOTICES (Warning: undefined constant x assumed 'x' etc.); If not, the hosting probably upgraded/changed something.
The next suspect would be that thing which's name eludes me right now. It's when you have http://url.com/download.php?file=xxx Apache sees .php and sends text/php header. I don't remember what that was called but you fix it with mod_rewrite.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With