8
votes

Im having issues with my code being able to open a zip file that i have uploaded and moved into a folder, the zip file uploads fine and you can open it in any Zip program however, when i attempt to open it with ZipArchive to extract the data it errors.

    $path = "../"; // Upload directory      
    $count = 0;

    foreach ($_FILES['files']['name'] as $f => $name) {     
       if(move_uploaded_file($_FILES["files"]["tmp_name"][$f], $path . $name))
             $count++; // Number of successfully uploaded file
    }

    $kioskFile = $_FILES['files']['name'][0];
    $kioskFile = explode(".", $kioskFile);
    $kioskFile = $kioskFile[0];
    $zipFile = "../" . $kioskFile . ".zip";     

    $zip = new ZipArchive;
    $res = $zip->open($zipFile);
    if ($res === true) {
        $zip->extractTo("./");
        $zip->close();
    } else {
        echo "Error Cannot Open Zip File - Error Code: ";
    }

When i run the code it shows me a Error Code 19

ZIPARCHIVE::ER_NOZIP - 19

This is the error im getting, however the file exists and if i use zip_open, it returns that it can open the zip file.

Any help would be very greatful

EDIT1 If i upload a zip file that i manually create (using a zip program) then the upload works fine. However if i use a ZipArchive created zip file, then it instantly errors with a error 19.

EDIT2 I have now added a check to make sure the file exists in the right directory and also put a print of the location also, both match, however still the same issue. Error 19

    $path = "../"; // Upload directory      
    $count = 0;

    foreach ($_FILES['files']['name'] as $f => $name) {     
       if(move_uploaded_file($_FILES["files"]["tmp_name"][$f], $path . $name))
             $count++; // Number of successfully uploaded file
    }

    $kioskFile = $_FILES['files']['name'][0];
    $kioskFile = explode(".", $kioskFile);
    $kioskFile = $kioskFile[0];
    $realpath = realpath("../");
    $zipFile = $realpath . "\\" .  $kioskFile . ".zip";     

    if (file_exists($zipFile)) {
        $extract = zip_extract($zipFile, "../");
        if ($extract === TRUE) {

        } else {
            echo "The file " . $zipFile . " cannot be opened";  
        }
    } else {
        echo "The file " . $zipFile . " does not exist";
        die();
    }

UPDATE1 So i think ive narrowed it down to either this bit of code, or the download script that i use to download the .zip file from the system, if i leave the zip on the system and use the exact same bit of code it works fine.

Here is my download code, maybe ive missed something on this that is causing the issue.

    $fileID = $_GET['id'];
    $backupLoc = "backups/";
    $sql = "SELECT * FROM backups WHERE id = '" . addslashes($fileID) .  "' LIMIT 1";
    $res = mysql_query($sql);
    $row = mysql_fetch_array($res); 
    $backupFile = $row['backupFile'];
    $zipFile = $backupLoc . "/" . $backupFile . ".zip";
    $zipSize = filesize($zipFile);

    header('Content-type: application/zip');
    header('Content-Disposition: attachment; filename="' . basename($zipFile). '"'); 
    ob_end_flush();
    readfile($zipFile);
    exit;
    die();
2
Have you done a var dump for path and file name? - Marco Mura
Yup file name is 100% correct, i can even put it into my zip program (the url that is given from php) and it will go and open it in the zip program so the location of the zip and its filename are correct - Clifford Yeti Mapp
I already researched that URL before posting, and the Poster of that had used fwrite to make his Zip File, this is a zip file that was created using ZipArchive in the first place - Clifford Yeti Mapp
have you tried open other zip created from other systems? - Marco Mura

2 Answers

4
votes

Open the archive with a text or hex editor and make sure you have the 'PK' signature at the start of the file. If you have any HTML before that signature, it would suggest that your buffers are not being cleaned or are being flushed when they should not be, meaning that PHP ZipArchive will assume an invalid archive.

4
votes

It was the download.php file that was causing the issue, here is the solution. which was to do a OB CLEAN rather than a Flush

    ///echo "<div style='padding: 50px;'>Please Wait .....</div>";
    $fileID = $_GET['id'];
    $backupLoc = "backups/";
    $sql = "SELECT * FROM backups WHERE id = '" . addslashes($fileID) .  "' LIMIT 1";
    $res = mysql_query($sql);
    $row = mysql_fetch_array($res); 
    $backupFile = $row['backupFile'];
    $zipFile = $backupLoc . "/" . $backupFile . ".zip";
    $zipSize = filesize($zipFile);

    header('Content-type: application/zip');
    header('Content-Disposition: attachment; filename="' . basename($zipFile). '"'); 
    //ob_end_flush();
    ob_end_clean(); 
    readfile($zipFile);
    exit;
    die();