5

I'm having issues when attempting to serve a .docx file using Php. When uploading the file I detect the file mime type and upload the file using the file with the correct extension based on the mime type; e.g. below:

application/msword - doc
application/vnd.openxmlformats-officedocument.wordprocessingml.document - docx

When attempting to serve the files for download, I do the reverse in detecting the extension and serving based on the mime type e.g.

public static function fileMimeType($extention) {

        if(!is_null($extention)) {
            switch($extention) {
                case 'txt':
                    return 'text/plain';
                    break;
                case 'odt':
                    return 'application/vnd.oasis.opendocument.text';
                    break;
                case 'doc':
                    return 'application/msword';
                    break;
                case 'docx':
                    return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                    break;
                case 'jpg':
                    return 'image/jpeg';
                    break;
                case 'png':
                    return 'image/png';
                    break;
                case 'pdf':
                    return 'application/pdf';
                    break;
                default:
                    break;
            }
        }

}

All files appear to download correctly and open fine but when attempting to open a docx file, Word (on multiple files) throws a error stating the file is corrupt.

Any ideas would be great, thanks.

Edit #1

try {

 $file = new Booking_Document((int)$get_data['bookingDocument']);
 header('Content-Type: ' . Booking_Document::fileMimeType($file->getDocumentType()));
 header('Content-Disposition: attachment; filename=' . $file);
 header('Expires: 0');
 header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
 header('Pragma: public');
 echo readfile(Zend_Registry::get(static::$_uploadDir).$this->_id);
} catch (Exception $e) {
 View_Helpers_FlashMessages::addMessage(array('message' => $e->getMessage(), 'type' => 'error'));
}
exit;

FIXED

Prior to calling readfile() I added ob_clean() and flush() which appears to have fixed the problem.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • 2
    `case ('jpg' || 'jpeg'):` doesn't work, you need to write `case 'jpg': case 'jpeg':`. – deceze Jan 05 '11 at 09:53
  • Similar question, might help: http://stackoverflow.com/questions/179315/downloading-docx-from-ie-setting-mime-types-in-iis – kapa Jan 05 '11 at 09:54
  • What's the result you receive on the client side? Is it a valid file when saved to disk? – deceze Jan 05 '11 at 09:55
  • Is the correct MIME header being sent? Check using Firebug/another browser console. – lonesomeday Jan 05 '11 at 09:55
  • Hmmm...okay. Surely this can't be the problem? I don't receive Php warnings or errors. –  Jan 05 '11 at 09:55
  • the mime looks correct. what other debugging have you done? have you made sure the file uploads correctly, are other files working with the same script, have you made sure the correct mime is being selected when you serve the file? – robjmills Jan 05 '11 at 09:56
  • And to expand on deceze's point, nothing below `case ('jpg' || 'jpeg')` will work, because that condition will always pass for a non-empty string. – lonesomeday Jan 05 '11 at 09:56
  • Yes, the file is correct and can be viewed in OpenOffice. But Word reports a corrupt file. The file contains text only. All other files work correctly with the upload and download. Ok I've changed the jpeg case. –  Jan 05 '11 at 09:58
  • 2
    You could try using good old `'application/octet-stream'` instead. Not quite as good as using the correct mime type, but worth trying to see if it works. – Spudley Jan 05 '11 at 09:58
  • application/octet-stream doesn't appear to work either. Word reports the file is corrupt and allows the contents to be recovered. Once recovered, the content can be viewed. But from a practical use, having to do this each time isn't useful. –  Jan 05 '11 at 10:03

2 Answers2

5

Fixed; prior to calling readfile() I added ob_clean() and flush() which appears to have fixed the problem.

0

I had a similar problem some days ago. It was due to some characters being output just before the file was read. These chars were inserted at the beginning of the downloaded file, making it appear as corrupted when I tried to open it (PDF in this case).

AJJ
  • 7,365
  • 7
  • 31
  • 34
  • Cheers but there doesn't appear to be any characters being output before the file. I've modified above to show how the file is output. –  Jan 05 '11 at 10:04