PHP - 在拉链中添加拉链时损坏的拉链

时间:2016-12-18 18:29:13

标签: php zip

我目前正在开发一个用PHP制作的工具(这项技术相当新手......),它应该生成带有一组文件的zip文件。这组文件可以是:

  • 基本文件(多种格式)
  • 完整目录(将作为新的压缩文件添加到生成的zip文件中 - 最终ZIP内的ZIP)

问题是,当zip文件包含简单文件时,它会正确下载,但是当文件包含"完整目录zip文件时#34;然后生成的ZIP文件被破坏......

在我目前正在使用的代码下面(抱歉,如果它有点乱,但这是我第一次使用PHP ...)

function ZipFiles($fileArr,$id) {
    $destination = "{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/WMDConfigFiles_".$id.".zip";
    $valid_files = array();

    //if files were passed in...
    if(is_array($fileArr)) {
        //cycle through each file
        foreach($fileArr as $file) {            

            if(is_dir($file)) {
                //If path is a folder we zip it and put it on $valid_files[]
                $resultingZipPath = "{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/".basename($file)."_FOLDER.zip";
                ZipFolder($file,$resultingZipPath );
                $valid_files[] = $resultingZipPath ;    
            }
            else {              
                //If path is not a folder then we make sure the file exists
                if(file_exists("{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/".$file)) {
                    $valid_files[] = $file;                 
                }
            }
        }
    }
    //if we have good files...
    if(count($valid_files)) {
        //create the archive
        $zip = new ZipArchive();
        if($zip->open($destination,ZIPARCHIVE::CREATE) !== true) {
            return false;
        }
        //add the files
        foreach($valid_files as $file) {
            $zip->addFile("{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/".$file,$file);
        }

        $zip->close();

        return $destination;
    }
    else
    {
        return "";
    }
}

function ZipFolder($source, $destination) {

    // Initialize archive object
    $folderZip = new ZipArchive();
    $folderZip->open($destination, ZipArchive::CREATE | ZipArchive::OVERWRITE);

    // Create recursive directory iterator
    /** @var SplFileInfo[] $files */
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($source),
        RecursiveIteratorIterator::LEAVES_ONLY
    );

    foreach ($files as $name => $file)
    {
        // Skip directories (they would be added automatically)
        if (!$file->isDir())
        {
            // Get real and relative path for current file
            $filePath = $file->getRealPath();
            $relativePath = substr($filePath, strlen($source) + 1);

            // Add current file to archive
            $folderZip->addFile($filePath, $relativePath);
        }
    }

    // Zip archive will be created only after closing object
    $folderZip->close();

}

在它上面我们可以看到两个功能:

  • ZipFiles:是通过传递列表/数组(包含将添加到最终ZIP中的文件和文件夹列表)和ID参数调用的主要功能,该参数仅用于生成不同的文件名。 (可以忽略)
  • ZipFolder:为上面提到的列表/数组中的每个文件夹(不是文件)调用此函数,以便压缩该文件夹并创建一个zip文件以将其添加到最终文件中。 (根据我在How to zip a whole folder using PHP中找到的内容)

我尝试了很多像上面提到的内容,比如关闭所有文件,或者在拉链内避免空拉链,但没有任何效果......

Zip inside zip (php)

也许我错过了一些东西(很可能是:))但是我已经没法了,所以任何帮助/指导都会受到赞赏。

如果需要更多信息,请告诉我并发布。

提前多多感谢!!

1 个答案:

答案 0 :(得分:0)

终于找到了问题。似乎文件是正确生成的,但是当从PHP下载文件时,当大小大于具体数字时会出现问题。 这是由于标题定义中消息长度的错误定义:

header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Length: ".filesize($zippedFile));
header("Content-Disposition: attachment; filename=".$zippedFile);   
header("Content-type: application/zip");
header("Content-Transfer-Encoding: binary");

即使我猜这可能不是一个正确的做法,我删除了Content-Length条目,现在我得到了正确的文件,尽管它的大小。