php压缩多个文件提示损坏文件

时间:2013-11-19 12:07:39

标签: php file zip

刚才我创建了一个zip生成脚本,脚本工作正常,同时压缩一个文件或两个三个文件但是当我尝试下载包含30个以上文件总数为166MB的整个zip目录时,脚本会生成2KB的压缩文件但提示存档格式未知或已损坏

<?php
$error = ""; //error holder

$post = $_POST; 
$file = $_GET['file'];

//die($file);
$file_folder = $_GET['file']; // folder to load files
if(extension_loaded('zip'))
{ 
// Checking ZIP extension is available

// Checking files are selected
$zip = new ZipArchive(); // Load zip library 
$zip_name = time().".zip"; // Zip name


if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE)
{ 
 // Opening zip file to load files
$error .= "* Sorry ZIP creation failed at this time";
}

if (is_dir($file)) {
    if ($dh = opendir($file)) {
        while (($filename = readdir($dh)) !== false) {
            if(!is_dir($file . $filename)){
                $zip->addFile($file . $filename); // Adding files into zip

            }
        }
        closedir($dh);
    }
} else {
    if(file_exists($file)){
        $zip->addFile($file); // Adding files into zip
    } else {
        $error = "* File not found";
    }
}
$zip->close();
if(file_exists($zip_name))
{
// push to download the zip
header('Content-type: application/zip');
header('Content-Disposition: attachment; filename="'.$zip_name.'"');
readfile($zip_name);
// remove zip file is exists in temp path
unlink($zip_name);
}


}
else
$error .= "* You dont have ZIP extension";

if($error!=''){
    header("Location: index.php?cat=62&msg=Download currently not available, sorry for inconvenience.");
}
?>

任何帮助将不胜感激:)

2 个答案:

答案 0 :(得分:2)

希望这不适用于生产服务器,因为允许某人设置要压缩的路径是非常不安全的,但如果不是......

如果没有调试代码,请尝试类似的事情(更新以处理文件大小超过phps内存限制)

<?php
//set path
$path = isset($_GET['file']) ? $_GET['file'] : null;

//check exists
if($path != null && file_exists($path)){
    //out zip name
    $zip_out = time().".zip";
    //zip it or return error
    if(Zippit::zipDir($path, $zip_out) === false){
        exit(header("Location: ./index.php?cat=62&msg=*+You+dont+have+ZIP+extension"));
    }

    // push to download the zip
    header('Content-type: application/zip');
    header('Content-Disposition: attachment; filename="'.basename($zip_out).'"');
    header('Content-Length: '.sprintf("%u", filesize($zip_out)));
    readfile($zip_out);
    // remove zip file is exists in temp path
    unlink($zip_out);
    exit();
}else{
    exit(header("Location: ./index.php?cat=62&msg=*+File+not+Found"));
}

/**
 * Zippit
 * usage: Zippit::zipDir($path, $zip_out);
 */
class Zippit {
    /**
     * Add files and sub-directories in a folder to zip file.
     * @param string $folder
     * @param ZipArchive $zipFile
     * @param int $exclusiveLength Number of text to be exclusived from the file path.
     */
    private static function folderToZip($folder, &$zipFile, $exclusiveLength) {
        $handle = opendir($folder);
        while (false !== $f = readdir($handle)) {
            if ($f != '.' && $f != '..') {
                $filePath = $folder."/".$f;
                // Remove prefix from file path before add to zip.
                $localPath = substr($filePath, $exclusiveLength);
                if (is_file($filePath)) {
                    $zipFile->addFile($filePath, $localPath);
                } elseif (is_dir($filePath)) {
                    // Add sub-directory.
                    $zipFile->addEmptyDir($localPath);
                    self::folderToZip($filePath, $zipFile, $exclusiveLength);
                }
            }
        }
        closedir($handle);
    }
    /**
     * Zip a folder (include itself).
     *   Usage:
     *   Zippit::zipDir('/path/to/sourceDir', '/path/to/out.zip');
     *
     * @param string $sourcePath Path of directory to be zip.
     * @param string $outZipPath Path of output zip file.
     */
    public static function zipDir($sourcePath, $outZipPath)
    {
        $pathInfo   = pathInfo($sourcePath);
        $parentPath = $pathInfo['dirname'];
        $dirName    = $pathInfo['basename'];

        $z = new ZipArchive();
        if (!$z->open($outZipPath, ZIPARCHIVE::CREATE)) {
            return false;
        }
        $z->addEmptyDir($dirName);
        self::folderToZip($sourcePath, $z, strlen($parentPath."/"));
        $z->close();
    }
}
?>

答案 1 :(得分:0)

试试这个:

<?php
$error = ""; //error holder

$post = $_POST; 
$file = $_GET['file'];

//die($file);
$file_folder = $_GET['file']; // folder to load files
if(extension_loaded('zip'))
{ 
// Checking ZIP extension is available

// Checking files are selected
$zip = new ZipArchive(); // Load zip library 
$zip_name = time().".zip"; // Zip name


if($zip->open($zip_name, ZIPARCHIVE::CREATE)!==TRUE)
{ 
 // Opening zip file to load files
$error .= "* Sorry ZIP creation failed at this time";
}

if (is_dir($file)) {
    if ($dh = opendir($file)) {
        while (($filename = readdir($dh)) !== false) {
            if(!is_dir($file . $filename)){
                $zip->addFile($file . $filename); // Adding files into zip

            }
        }
        closedir($dh);
    }
} else {
    if(file_exists($file)){
        $zip->addFile($file); // Adding files into zip
    } else {
        $error = "* File not found";
    }
}
$zip->close();
if(file_exists($zip_name))
{
    // push to download the zip
    header('Content-type: application/zip');
    header('Content-Disposition: attachment; filename="'.$zip_name.'"');
    $zip_file = file_get_contents($zip_name);
    print $zip_file;
    // remove zip file is exists in temp path
    unlink($zip_name);
}


}
else
$error .= "* You dont have ZIP extension";

if($error!=''){
    header("Location: index.php?cat=62&msg=Download currently not available, sorry for inconvenience.");
}
?>

我所做的是将“readfile”替换为:

    $zip_file = file_get_contents($zip_name);
    print $zip_file;

我不知道造成拉链腐败的原因。

我希望这会有所帮助。