2

I'm struggling around with a simple PHP functionality: Creating a ZIP Archive with some files in.

The problem is, it does not create only one file called filename.zip but two files called filename.zip.a07600 and filename.zip.b07600. Pls. see the following screenshot:

no comment, just have a look...

The two files are perfect in size and I even can rename each of them to filename.zip and extract it without any problems.

Can anybody tell me what is going wrong???

function zipFilesAndDownload_Defect($archive_file_name, $archiveDir, $file_path = array(), $files_array = array()) {
    // Archive File Name
    $archive_file = $archiveDir."/".$archive_file_name;
    // Time-to-live
    $archiveTTL = 86400; // 1 day
    // Delete old zip file
    @unlink($archive_file);
    // Create the object
    $zip = new ZipArchive();
    // Create the file and throw the error if unsuccessful
    if ($zip->open($archive_file, ZIPARCHIVE::CREATE) !== TRUE) {
        $response->res = "Cannot open '$archive_file'";
        return $response;
    }
    // Add each file of $file_name array to archive
    $i = 0;
    foreach($files_array as $value){
        $expl = explode("/", $value);
        $file = $expl[(count($expl)-1)];
        $path_file = $file_path[$i] . "/" . $file;
        $size = round((filesize ($path_file) / 1024), 0);
        if(file_exists($path_file)){
            $zip->addFile($path_file, $file);
        }
        $i++;
    }
    $zip->close();  
    // Then send the headers to redirect to the ZIP file
    header("HTTP/1.1 303 See Other"); // 303 is technically correct for this type of redirect
    header("Location: $archive_file");
    exit;
}

The code which calls the function is a file with a switch-case... it is called itself by an ajax-call:

case "zdl":
    $files_array = array();
    $file_path = array();
    foreach ($dbh->query("select GUID, DIRECTORY, BASENAME, ELEMENTID from SMDMS where ELEMENTID = ".$osguid." and PROJECTID = ".$osproject.";") as $subrow) {
        $archive_file_name = $subrow['ELEMENTID'].".zip";
        $archiveDir = "../".$subrow['DIRECTORY'];
        $files_array[] = $archiveDir.DIR_SEPARATOR.$subrow['BASENAME'];
        $file_path[] = $archiveDir;
    }
    zipFilesAndDownload_Defect($archive_file_name, $archiveDir, $file_path, $files_array);
break;

One more code... I tried to rename the latest 123456.zip.a01234 file to 123456.zip and then unlink the old 123456.zip.a01234 (and all prior added .a01234 files) with this function:

function zip_file_exists($pathfile){
    $arr = array();
    $dir = dirname($pathfile);
    $renamed = 0;
    foreach(glob($pathfile.'.*') as $file) {
        $path_parts = pathinfo($file);
        $dirname = $path_parts['dirname'];
        $basename = $path_parts['basename'];
        $extension = $path_parts['extension'];
        $filename = $path_parts['filename'];
        if($renamed == 0){
            $old_name = $file;
            $new_name = str_replace(".".$extension, "", $file);
            @copy($old_name, $new_name);
            @unlink($old_name);
            $renamed = 1;
            //file_put_contents($dir."/test.txt", "old_name: ".$old_name." - new_name: ".$new_name." - dirname: ".$dirname." - basename: ".$basename." - extension: ".$extension." - filename: ".$filename." - test: ".$test);
        }else{
            @unlink($file);
        }
    }
}

In short: copy works, rename didn't work and "unlink"-doesn't work at all... I'm out of ideas now... :(

ONE MORE TRY: I placed the output of $zip->getStatusString() in a variable and wrote it to a log file... the log entry it produced is: Renaming temporary file failed: No such file or directory. But as you can see in the graphic above the file 43051221.zip.a07200 is located in the directory where the zip-lib opens it temporarily.

Thank you in advance for your help!

Ingmar Erdös
  • 517
  • 8
  • 18
  • How you have called this function? Is it call in any loop? – AnkiiG Nov 18 '15 at 11:57
  • Thank you for your good idea. But the function is called only once. In other case - where the files are served by scandir - it works perfect. In this case I pick the files and paths out of a database. – Ingmar Erdös Nov 18 '15 at 13:07

2 Answers2

2

So, after struggling around for days... It was so simple:

Actually I work ONLY on *nix Servers so in my scripts I created the folders dynamically with 0777 Perms. I didn't know that IIS doesn't accept this permissions format at all!

So I remoted to the server, right clicked on the folder Documents (the hierarchically most upper folder of all dynamically added files and folders) and gave full control to all users I found.

Now it works perfect!!! The only thing that would be interesting now is: is this dangerous of any reason???

Thanks for your good will answers...

Ingmar Erdös
  • 517
  • 8
  • 18
0

My suspicion is that your script is hitting the PHP script timeout. PHP zip creates a temporary file to zip in to where the filename is yourfilename.zip.some_random_number. This file is renamed to yourfilename.zip when the zip file is closed. If the script times out it will probably just get left there.

Try reducing the number of files to zip, or increasing the script timeout with set_time_limit()

http://php.net/manual/en/function.set-time-limit.php

QuantumTiger
  • 970
  • 1
  • 10
  • 22
  • Thank you for your suggestion but this can't be the problem: I work with two test cases, one with 2 files and another with 4 files. The files are sized around 700 Kb as you can see in the screenshot above... – Ingmar Erdös Nov 18 '15 at 13:10
  • Intriguing. I've copied your function and run it locally with no issue. Can you share the code which calls it? – QuantumTiger Nov 18 '15 at 13:33
  • I added the code snipped that is responsible for the call of the function in the original posting above. The most interesting fact is, that it was already working perfect until I added DB-functionality in the function above... – Ingmar Erdös Nov 19 '15 at 09:15