从PHP下载时Word / Excel文件已损坏
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了从PHP下载时Word / Excel文件已损坏,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3905字,纯文字阅读大概需要6分钟。
内容图文
![从PHP下载时Word / Excel文件已损坏](/upload/InfoBanner/zyjiaocheng/804/f77e7cde74a5474e9a1a3e783e97f942.jpg)
我正在构建一个简单的文件上传/文件下载功能到我的数据库中.唯一复杂的部分是所有文件都需要使用我的花式shmancy加密方法加密.
所以我做的是创建一个SQL条目,存储如下内容:id_file,filename,extension,size,dateadded等
然后,一旦我获得了id_file,我获取文件内容,加密它们,然后将内容作为[id_file] .txt保存到我的服务器.
然后这是再次下载文件的代码:
header("Pragma: public");
header('Content-Disposition: attachment;filename="'.$file['name'].'.'.$file['extension'].'"');
header('Cache-Control: max-age=0');
echo someFunctionIMadeForGettingAndDecryptingFileContents($_GET['id_file']);
exit;
非常简单的东西,适用于所有文件类型EXCEPT .docx和.xlsx.下载.docx或.xlsx文件时,Office给出了一个错误,说“Word在”NAME OF FILE“中找到了不可读的内容.你想恢复这个文件的内容吗?如果你相信来源…… bla bla”我那么单击“是”.它思考了一下,文件打开就好了.但显然我不能让我的客户使用它,如果他们每次都会得到那个错误.
我编写的代码适用于所有其他文件类型.即使.doc,.xls和.zip文件也能正常工作.
我的第一个想法是看看标题.我尝试过各种各样的解决方案,例如这里列出的解决方案:
why my downloaded file is alwayes damaged or corrupted?
PHP downloading excel file becomes corrupt
那些没用.
我知道一个问题可能是文件中添加了额外的填充或空白区域.但是,如果我上传.txt文件然后再次下载…我可以看到没有任何额外的添加.
如果我MD5原始文件(good.docx)和原始文件的下载版本(bad.docx),则哈希值不同.
如果我将good.docx更改为good.zip并解压缩存档.然后为bad.docx做同样的事情.然后MD5两个目录,哈希是相同的.我在good.zip和bad.zip中散列了每个文件,每个文件哈希都是一样的.
还要注意,在我的服务器上的其他地方,我使用PHPWord和PHPExcel动态生成Office文件,这些文件都下载得很好.我用于PHPExcel的头文件/代码是:
header("Pragma: public");
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$filename.'.xlsx"');
header('Cache-Control: max-age=0');
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
$objWriter->save('php://output');
exit;
(是的,我尝试在上面的其他代码中使用“Content-Type”标题,但这没有帮助.)
我也尝试将文件保存在我的服务器上,下载并打开它.在完成该过程时,我得到了同样的错误.这是我以前用来做的代码:
$f=fopen("/myPath/temp.docx","w");
fwrite($f,someFunctionIMadeForGettingAndDecryptingFileContents($_GET['id_file']));
fclose($f);
exit;
我试过创建一个名为“blank.docx”的空Word文件.然后这样做而不是保存新文件的函数….它用解密的文件内容替换blank.docx的内容.但是当在该过程之后下载blank.docx时,我得到了所有相同的…一个错误,但它最终会打开.最初在blank.docx上的文件属性(如Template:Normal.dotm)都不在服务修改的blank.docx上.
我正在使用Office 2007
UPDATE
这是一个下载文件的好(原始)版本的链接:http://empowerdb.org/good.docx
这是一个下载该文件的错误(已处理)版本的链接:
http://empowerdb.org/bad.docx
解
正如Llama先生在下面指出的那样,我的加密函数正在减少一些额外的空字节.但事实证明,罪魁祸首并不像你想象的那么明显.这是我的加密:
trim(base64_encode(IV.mcrypt_encrypt(MCRYPT_RIJNDAEL_128,ENCKEY,$contents,MCRYPT_MODE_CBC,IV)))
问题不在于trim()或base64_encode().它是使用mcrypt函数.我解决这个问题的方法是在传递我的文件内容以进行加密之前我做了另一个base64_encode().所以这样……
$file_contents_encrypted=base64_encode(myEncryptionFunction($file_contents));
当然,解密时也是如此.
base64_encode在技术上是运行两次.但我可以看到在这种情况下需要如何在mcrypt之前运行,因为.docx和.xlsx的独特zip格式
解决方法:
您的解密函数正在文件末尾删除空字节.
good.docx文件以四个0x00字节结束,而bad.docx文件以none结尾.除了那些丢失的字节,文件是相同的.
$wc -c good.docx
25123 good.docx
$wc -c bad.docx
25119 bad.docx
$tail -c 32 good.docx | od -x
0000000 6666 6365 7374 782e 6c6d 4b50 0605 0000
0000020 0000 0010 0010 041c 0000 5df1 0000 0000
$tail -c 32 bad.docx | od -x
0000000 7469 4568 6666 6365 7374 782e 6c6d 4b50
0000020 0605 0000 0000 0010 0010 041c 0000 5df1
如果跳过good.docx的最后四个字节,则md5总和完全匹配:
$head -c -4 good.docx | md5sum
fbd32fbcc02d62dfd8bd39d390252a4b *-
$cat bad.docx | md5sum
fbd32fbcc02d62dfd8bd39d390252a4b *-
内容总结
以上是互联网集市为您收集整理的从PHP下载时Word / Excel文件已损坏全部内容,希望文章能够帮你解决从PHP下载时Word / Excel文件已损坏所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。