Alex Martinez
Alex Martinez

Reputation: 53

Creating ZIP File in PHP coming up with Browser errors, not Script errors

I created a code to backup an entire website & automatically download it on a single click. Here is what my code looks like:

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);

Now this code was working good for awhile, but it seems today it doesn't want to work. The thing is, it's not a PHP script error. I've checked my error logs and nothing is showing up. It appears to be a browser error, but each browser displays a different message:

Chrome says "This webpage is not available" Firefox says "The connection was reset" Internet Explorer says "This page can't be displayed"

Even though these errors come up, the ZIP file is still being created and I can download it from the server.

Here is a list of things I've tried after extensive research:

1) I removed the code to have the ZIP file download automatically (all code written after I close the ZIP file). Still get the browser errors.

2) I read that it's possible too many files are getting opened and its going over my limit. I added to the code to close and reopen the ZIP file after every 200 files. Still didn't work.

3) I limited the amount of files to ZIP. Everything was working fine below 500. Between 500 to 1,000 files, the code would work a partial amount of the time. Sometimes it would go through fine, the others it would give me the browser error. After 1,000 or so it just wouldn't work properly at all.

The hosting is through GoDaddy.

PHP Version is 5.2.17

max_execution_time is set at 240 (the code never goes this long, usually only takes about 30 sec to run)

memory_limit is set at 500M (more than twice the size of all the files combined)

I'm at a loss, I really don't know what is going on because this code was working just fine for 1,500 files a few weeks ago. And again, the ZIP file is still being created, there are no PHP errors and it's only the Browsers that are coming back with these errors.

Upvotes: 2

Views: 2014

Answers (2)

user2537908
user2537908

Reputation: 1

instantate an iterator (before creating the zip archive, just in case the zip file is created inside the source folder) and traverse the directory to get the file list.

See More Code At:click me

Upvotes: 0

tftd
tftd

Reputation: 17032

I don't know what's wrong with your code, but I'm using the code below and it has been working forever with me.

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');

Upvotes: 1

Related Questions