无法在Windows Explorer中打开由PHP Zip Archive生成的zip文件

4
当我尝试打开由PHP Zip Archive生成的zip文件时,会显示一个警告信息:
“Windows无法打开该文件夹。在Windows Explorer中打开'filename'被压缩的(zipped)文件夹是无效的。”
但是我可以通过7-zip打开文件。由于某些原因,我必须确保Windows Explorer可以打开zip文件。我生成zip文件时是否存在问题?请帮忙!
function create_a_zip($files = array(),$dest = '',$root_folder,$overwrite = false) {
        if(file_exists($dest) && !$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();
            if($zip->open($dest,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
                return false;
            }
            foreach($valid_files as $valid_file) {
                if(is_dir($valid_file) === true){
                    foreach(glob($valid_file . '/*') as $file){
                        $zip->addFile($file, $root_folder . $file);
                    }

                }else if (is_file($valid_file) === true){
                    $zip->addFile($valid_file, $root_folder . $valid_file);
                }
            }
            $zip->close();

            return file_exists($dest);
        }
        else
        {
            return false;
        }
    }
5个回答

17

对我来说,解决办法是在输出zip文件内容之前使用ob_end_clean()(如评论中@Ywis所指出的)...

ob_end_clean();
readfile($zipfilename); // outputs zip file's content

即使在此之前您未输出任何字符,也是如此。


3

我认为问题的起源是:

$zip->addFile($file,$file);

除非您的php脚本和要添加到zip的文件在同一个目录中,否则您需要包含文件路径。addFile中的第二个参数是zip文件内的文件名,因此如果您的$file变量包含路径,则问题可能来自于此。尝试将代码更改为:

$filenameonly = preg_replace("/(.*)\/?([^\/]+)/","$2",$file);
$zip->addFile($file,$filenameonly );

这将剥离文件路径(如果有的话),并仅为addFile中的第二个变量留下文件名。

如果这可以解决您的问题,那么你就可以确定问题出在文件名上,并且可以轻松定位它。


谢谢您的建议。但是我只使用字母、数字、点(.)和下划线(_)作为路径。因此路径中没有空格。 - Ywis
非英语字符怎么办? - Flot2011
经过数小时的代码追踪,我终于发现路径名并不是问题所在。在服务器上生成的压缩文件是正确的(可以通过Windows内置的Zip实用程序打开),而下载的压缩文件是 不正确的!文件传输时出了什么问题吗?我比较了它们的文件大小,它们完全相同......无论如何,仍然感谢您的帮助! - Ywis
那么问题似乎出在你的解码方案上。你能发布一下创建头文件的代码吗? - Flot2011
我发现在 readfile() 之前应该有一个 **ob_end_clean()**。 - Ywis
我真的不太明白为什么。但我认为标头会影响输出缓冲区?所以当执行**readfile()**时,它会收集一些不应包括的字符。 - Ywis

1

Windows zip 不认识以“/”开头的路径

只需要从文件路径中删除第一个“/”即可。

像这样:

if ( substr($root_folder,0,1) == '/' ) {
    $root_folder = substr($root_folder,1);
}
$zip->addFile($file, $root_folder . $file);

0

你可以使用内置的文件系统函数,而不是使用 str_replace 字符串函数。

$zip->addFile(realpath($file), pathinfo($file, PATHINFO_BASENAME));

0

只需将绝对路径作为参数发送,例如$abspath。 然后在中使用它

$filenameonly = str_replace($abspath,"",$file);
$zip->addFile($file, $filenameonly);

它在Windows 8中百分之百工作,即使您压缩的文件在文件夹中也是如此。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接