使用PHP ZipArchive创建ODT文件出现损坏问题求助
问题原因及解决方案
ODT文件本质是遵循特定结构的ZIP压缩包,你生成的文件损坏,核心问题是没有满足ODT对ZIP包的强制规范:
- ODT要求
mimetype文件必须放在ZIP包的最开头,且必须以**无压缩(存储)**的方式添加,不能用默认的压缩算法。 - 你的代码用
addFromString统一处理所有文件,会对mimetype也进行压缩,同时无法保证它在包中的顺序,导致办公软件无法识别这个ODT文件。
修复步骤
1. 优先处理mimetype文件
在添加其他文件之前,单独添加mimetype,指定ZipArchive::CM_STORE(无压缩)参数:
// 先添加mimetype,必须放在最前面且无压缩 $zip->addFromString('mimetype', 'application/vnd.oasis.opendocument.text', ZipArchive::CM_STORE);
2. 调整代码逻辑,确保文件结构正确
修改create_zip函数,恢复文件存在性检查,同时保证mimetype的正确处理:
function create_zip($files = array(), $destination = '', $files2 = array(), $overwrite = false) { if(file_exists($destination) && !$overwrite) { return false; } $valid_files = array(); if(is_array($files)) { foreach($files as $file) { // 恢复文件存在性检查,避免无效文件被添加 if(file_exists($file)) { $valid_files[] = $file; } } } if(count($valid_files)) { $zip = new ZipArchive(); $openMode = $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE; if($zip->open($destination, $openMode) !== true) { return false; } // 关键:先添加mimetype,无压缩且放在最前 $zip->addFromString('mimetype', 'application/vnd.oasis.opendocument.text', ZipArchive::CM_STORE); $i=0; foreach($valid_files as $file) { $auxF = file_get_contents($file); if (!file_exists($file)) { echo "Erro em compactador.loc.php linha 136. $file <BR>"; continue; } // 其他文件用默认压缩即可 $zip->addFromString($files2[$i], $auxF); $i++; } $zip->close(); return file_exists($destination); } else { return false; } }
3. 验证ODT必需结构
确保你的文件列表包含ODT核心文件:
content.xml:文档内容styles.xml:样式定义meta.xml:元数据META-INF/manifest.xml:清单文件(必须正确列出所有包内文件,否则仍会损坏)
为什么解压重压缩后能正常?
7-Zip等工具在重新压缩时,会自动调整ZIP包结构(比如将mimetype移到开头并采用存储模式),修复了原文件的不规范问题,所以办公软件能识别修复后的文件。
内容的提问来源于stack exchange,提问作者Antonio Abrantes
相关产品推荐
相关产品推荐

