无法在Windows资源管理器中打开由PHP zip存档生成的zip文件

无法在Windows资源管理器中打开由PHP zip存档生成的zip文件,php,windows,zip,ziparchive,Php,Windows,Zip,Ziparchive,当我试图打开由PHPZIP存档生成的zip文件时,会出现一个警报,显示 “Windows无法打开该文件夹。压缩(压缩)文件夹 “文件名”无效。“在Windows资源管理器中打开时出错。” 但是我可以通过7-zip打开文件。出于某种原因,我必须确保zip文件可以由Windows资源管理器打开。生成zip文件时有问题吗?请帮忙 function create_a_zip($files = array(),$dest = '',$root_folder,$overwrite = false) {

当我试图打开由PHPZIP存档生成的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;
        }
    }

我认为问题的根源在于:

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

$filenameonly = preg_replace("/(.*)\/?([^\/]+)/","$2",$file);
$zip->addFile($file,$filenameonly );
这将去掉文件路径(如果有的话),只留下addFile中第二个变量的文件名


如果这能解决您的问题,您将确定问题出在您的文件名中,并且可以很容易地确定问题所在。

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

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

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

您可以使用内置的文件系统函数,而不是使用str_replace string函数

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

对我来说,解决方案是在输出zip文件内容之前使用
ob_end_clean()
(如@Ywis在注释中所指出的那样)


。。。即使在此之前没有输出任何字符。

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

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

像这样:

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

谢谢你的建议。但我只使用带有字母、数字、点(.)和下划线(41;的路径。所以路径中没有空格。那么非英语字符呢?经过数小时的代码跟踪,我终于发现路径名不是问题所在。服务器上生成的zip文件正确(可以通过Windows内置的zip实用程序打开),而下载的zip文件不正确!文件传输时是否有问题?我比较了他们的文件大小,他们完全一样……无论如何,还是要感谢你的帮助!那么问题似乎出在你的解码方案上。你能发布你的代码创建标题吗?我发现在readfile()之前应该有一个ob_end_clean()。
if ( substr($root_folder,0,1) == '/' ) {
    $root_folder = substr($root_folder,1);
}
$zip->addFile($file, $root_folder . $file);