在PHP中创建ZIP文件会出现浏览器错误,而不是脚本错误

时间:2013-04-02 00:46:23

标签: php zip

我创建了一个备份整个网站的代码。只需单击即可自动下载。这是我的代码:

if (file_exists("file.zip")) {
  unlink("file.zip");
}
$folder_array = array();
$file_array = array();
function listFolderFiles($dir){
  global $folder_array;
  global $file_array;
  $ffs = scandir($dir);
  foreach($ffs as $ff){
    if ($ff != '.' && $ff != '..') {
      if (is_dir($dir.'/'.$ff)) {
        $new_item = "$dir/$ff";
        $new_item = str_replace('..//','',$new_item);
        if ($new_item !== "stats") {
          array_push($folder_array, $new_item);
          listFolderFiles($dir.'/'.$ff);
        }
      }
      else {
        $new_item = "$dir/$ff";
        $new_item = str_replace('..//','',$new_item);
        if (($new_item !== "stats/logs") && ($new_item !== "stats/")) {
          array_push($file_array, $new_item);
        }
      }
    }
  }
}
listFolderFiles('../');
$zip = new ZipArchive;
if ($zip->open('file.zip', true ? ZIPARCHIVE::OVERWRITE:ZIPARCHIVE::CREATE) === TRUE) {
  foreach($folder_array as $folder) {
    $zip->addEmptyDir($folder);
  }
  foreach($file_array as $key => $file) {
    $file_path = "../$file";
    $zip->addFile($file_path, $file);
  }
}
$zip->close();
$file = "file.zip";
chmod("$file", 0700);
header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=". $file);
readfile($file);

现在这段代码运行良好一段时间,但今天似乎不想工作。问题是,它不是PHP脚本错误。我检查了我的错误日志,没有显示任何内容。它似乎是浏览器错误,但每个浏览器显示不同的消息:

Chrome说“此网页不可用” Firefox说“连接已重置” Internet Explorer说“此页面无法显示”

即使出现这些错误,ZIP文件仍在创建,我可以从服务器下载。

以下列出了经过广泛研究后我尝试过的事情:

1)我删除了代码以自动下载ZIP文件(在关闭ZIP文件后写入所有代码)。仍然会出现浏览器错误。

2)我读到可能有太多文件被打开并超出我的限制。我添加到代码中,每200个文件后关闭并重新打开ZIP文件。仍然没有奏效。

3)我将文件数量限制为ZIP。一切都在500以下正常工作。在500到1,000个文件之间,代码将在一定时间内工作。有时它会很好,其他它会给我浏览器错误。在1000左右之后它根本无法正常工作。

托管是通过GoDaddy。

PHP版本是5.2.17

max_execution_time设置为240(代码永远不会这么长,通常只需要大约30秒才能运行)

memory_limit设置为500M(超过所有文件组合大小的两倍)

我很茫然,我真的不知道发生了什么事,因为几周前这段代码对1,500个文件工作得很好。而且,ZIP文件仍在创建中,没有PHP错误,只有浏览器会出现这些错误。

2 个答案:

答案 0 :(得分:1)

我不知道你的代码有什么问题,但是我正在使用下面的代码,它一直在和我一起工作。

function create_zip($path, $save_as)
{
    if (!extension_loaded('zip'))
        throw new ErrorException('Extension ZIP has not been compiled or loaded in php.');
    else if(!file_exists($path))
        throw new ErrorException('The file/path you want to zip doesn\'t exist!');


    $zip = new ZipArchive();
    if (!$zip->open($save_as, ZIPARCHIVE::CREATE))
        throw new ErrorException('Could not create zip file!');

    $ignore = array('.','..');
    if($path == dirname($save_as))
        $ignore[] = basename($save_as);

    $path = str_replace('\\', '/', realpath($path));

    if (is_dir($path)) {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
        foreach ($files as $file) {
            $file = str_replace('\\', '/', $file);

            if( in_array(substr($file, strrpos($file, '/')+1),$ignore )) continue;

            $file = realpath($file);
            if (is_dir($file)) {
                $zip->addEmptyDir(str_replace($path . '/', '', $file . '/'));
            }
            else if (is_file($file)) {
                $zip->addFromString(str_replace($path . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($path)) {
        $zip->addFromString(basename($path), file_get_contents($path));
    }

    return $zip->close();
}

$zip = create_zip('/path/to/your/zip/directory', '/path/to/your/save.zip');

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename('/path/to/your/save.zip').'"');
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header('Content-Length: ' . filesize('/path/to/your/save.zip'));
echo readfile('/path/to/your/save.zip');

答案 1 :(得分:0)

即时创建迭代器(在创建zip存档之前,以防在源文件夹中创建zip文件)并遍历目录以获取文件列表。

See More Code At:click me