【问题标题】:Cannot open zip file in Windows Explorer which generated by PHP Zip Archive无法在 Windows 资源管理器中打开由 PHP Zip 存档生成的 zip 文件
【发布时间】:2012-11-30 13:41:44
【问题描述】:

当我尝试打开由 PHP Zip Archive 生成​​的 zip 文件时,会显示警告

"Windows 无法打开文件夹。压缩(压缩)文件夹 “文件名”无效。”在 Windows 资源管理器中打开时出错。

但我可以通过 7-zip 打开文件。出于某种原因,我必须确保 zip 文件可以通过 Windows 资源管理器打开。生成 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;
        }
    }

【问题讨论】:

    标签: php windows zip ziparchive


    【解决方案1】:

    对我来说,解决方案是在输出 zip 文件内容之前使用 ob_end_clean()(如 cmets 中的 @Ywis 所述)...

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

    ...即使在那之前你没有输出任何字符。

    【讨论】:

      【解决方案2】:

      我认为问题出在:

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

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

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

      这将去掉文件路径(如果有的话),只留下 addFile 中第二个变量的文件名。

      如果这能解决您的问题,您将确定问题出在您的文件名中,并且可以轻松查明问题。

      【讨论】:

      • 感谢您的建议。但我只使用带有字母、数字、点 (.) 和下划线 (_) 的路径。所以路径中没有空格。
      • 非英文字符呢?
      • 经过几个小时的跟踪代码,我终于发现路径名不是问题所在。服务器上生成的 zip 文件正确(可以通过 Windows 内置的 Zip 实用程序打开),而下载的 zip 文件错误!文件传输时有问题吗?我比较了它们的文件大小,它们完全一样......无论如何,仍然感谢您的帮助!
      • 那么问题似乎出在您的解码方案中。您可以发布创建标头的代码吗?
      • 我发现readfile()之前应该有一个ob_end_clean()。
      【解决方案3】:

      只需作为参数发送到绝对路径,例如$abspath。然后在

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

      即使在 Window 8 中它也能 100% 工作,甚至您压缩的文件都在文件夹中。

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

          Windows zip 无法识别以“/”开头的路径

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

          像这样:

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-03-08
            • 2022-10-15
            相关资源
            最近更新 更多