PHP ZipArchive in Windows beschädigt

Lesezeit: 7 Minuten

Benutzeravatar von Jesse Bunch
Jesse Haufen

Ich verwende die ZipArchive-Klasse von PHP, um eine ZIP-Datei mit Fotos zu erstellen und sie dann dem Browser zum Herunterladen bereitzustellen. Hier ist mein Code:

/**
 * Grabs the order, packages the files, and serves them up for download.
 *
 * @param string $intEntryID 
 * @return void
 * @author Jesse Bunch
 */
public static function download_order_by_entry_id($intUniqueID) {

    $objCustomer = PhotoCustomer::get_customer_by_unique_id($intUniqueID);

    if ($objCustomer):

        if (!class_exists('ZipArchive')):
            trigger_error('ZipArchive Class does not exist', E_USER_ERROR);
        endif;

        $objZip = new ZipArchive();
        $strZipFilename = sprintf('%s/application/tmp/%s-%s.zip', $_SERVER['DOCUMENT_ROOT'], $objCustomer->getEntryID(), time());

        if ($objZip->open($strZipFilename, ZIPARCHIVE::CREATE) !== TRUE):

            trigger_error('Unable to create zip archive', E_USER_ERROR);

        endif;          

        foreach($objCustomer->arrPhotosRequested as $objPhoto):

            $filename = PhotoCart::replace_ee_file_dir_in_string($objPhoto->strHighRes);
            $objZip->addFile($filename,sprintf('/press_photos/%s-%s', $objPhoto->getEntryID(), basename($filename)));

        endforeach;

        $objZip->close();

        header('Last-Modified: '.gmdate('D, d M Y H:i:s', filemtime($strZipFilename)).' GMT',  TRUE, 200);
        header('Cache-Control: no-cache', TRUE);
        header('Pragma: Public', TRUE);
        header('Expires: ' . gmdate('D, d M Y H:i:s', time()) . ' GMT', TRUE);
        header('Content-Length: '.filesize($strZipFilename), TRUE);
        header('Content-disposition: attachment; filename=press_photos.zip', TRUE);

        header('Content-Type: application/octet-stream', TRUE);

        ob_start();
        readfile($strZipFilename);
        ob_end_flush();
        exit;

    else:

        trigger_error('Invalid Customer', E_USER_ERROR);

    endif;

}

Dieser Code funktioniert wirklich gut mit allen Browsern außer IE. In IE wird die Datei korrekt heruntergeladen, aber das ZIP-Archiv ist leer. Beim Versuch, die Dateien zu extrahieren, teilt mir Windows mit, dass das ZIP-Archiv beschädigt ist. Hatte jemand dieses Problem schon einmal?

Bearbeiten Update: Nach dem Vorschlag von @profitphp habe ich meine Header wie folgt geändert:

header("Cache-Control: public");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
//header("Content-Description: File Transfer");
//header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"pressphotos.zip\"");
//header("Content-Transfer-Encoding: binary");
header("Content-length: " . filesize($strZipFilename));

Hier ist auch ein Screenshot des Fehlers in Windows nach dem Öffnen mit Firefox:

Alt-Text

Dieser Fehler tritt sowohl in IE als auch in Firefox unter Windows auf. Es funktioniert gut in Mac. Auch unter Windows scheint die Dateigröße korrekt zu sein:

Alt-Text

Bearbeiten #2 Dieses Problem ist gelöst. Siehe meine Antwort unten.

  • Hatte das gleiche Problem und diese Antwort war die Lösung für mich: [ZIP Archive sent by PHP is corrupted][1] [1]: stackoverflow.com/a/13528263/557311

    – MaRmar

    27. Februar 2015 um 16:02 Uhr

Benutzeravatar von CWSpear
CWSpeer

Ich hatte das gleiche Problem und meine Lösung ähnelte der richtigen Antwort in diesem Thread. Wenn Sie eine Datei in das Archiv stellen, können Sie keine absoluten Dateien haben (Dateien, die mit einem Schrägstrich beginnen), oder sie wird aus irgendeinem Grund nicht in Windows geöffnet.

Also hat es nicht funktioniert, weil er (Jesse Bunch, die ausgewählte Antwort zum Zeitpunkt des Schreibens dieses Artikels) den enthaltenden Ordner entfernt hat, sondern weil er den beginnenden Schrägstrich entfernt hat.

Ich habe das Problem durch Ändern behoben

$zip->addFile($file, $file); // $file is something like /path/to/file.png

zu

// we make file relative by removing beginning slash so it will open in Windows
$zip->addFile($file, ltrim($file, "https://stackoverflow.com/"));

und dann konnte es in Windows geöffnet werden!

Das ist wahrscheinlich der gleiche Grund, warum pclzip (Plahcinskis Antwort) funktioniert. Ich wette, es entfernt automatisch den Schrägstrich am Anfang.

Ohne a wäre ich darauf nicht gekommen besonderen Kommentar auf PHP ZipArchive::addFile Dokumentationsseite.

  • Das war das Problem für mich, hat sehr geholfen

    – Jake N

    15. März 2016 um 22:00 Uhr

Ich hatte vor kurzem ein ähnliches Problem wie du es beschrieben hast. Ich fand ZipArchive bestenfalls instabil.

Ich habe meine Probleme mit dieser einfachen Bibliothek gelöst

http://www.phpconcept.net/pclzip

include_once('libs/pclzip.lib.php');

function zip($source, $destination){
$zipfile = new PclZip($destination);
$v_list = $zipfile->create($source, '', $source); }

$source = Ordner, den ich komprimieren wollte $destination = Speicherort der Zip-Datei

Ich habe 2 Tage lang nach ZipArchive gesucht und dann alle Probleme mit PCLZip in 5 Minuten gelöst.

Ich hoffe, dies hilft Ihnen und allen anderen, die dieses Problem haben (da dies in der Nähe des obersten Google-Ergebnisses zu diesem Problem ist).

  • in einer Windows-Umgebung. Auf meiner Webseite hat es leider sehr gut funktioniert: es hat nur eine Datei gezippt statt mehrere Dateien,

    – Dev.Jaap

    16. April 2012 um 18:55 Uhr

  • hat bei mir unter Windows funktioniert. Wie Sie sagten, fast eine Stunde lang ZipArchive angesehen, und dies funktionierte in 2 Minuten. tnx!

    – Floon

    26. August 2013 um 14:02 Uhr

  • Tolle Bibliothek. Um es auf einem PHP7.1-Server zu verwenden, ändern Sie einfach die Methode “PclZip” in “__construct” und fügen Sie “(int)” hinzu, wo eine Ganzzahl erforderlich ist.

    – Phoka

    17. Juli 2017 um 16:34 Uhr

  • Toter Link für die Bibliothek

    – Ravi Mattar

    18. August 2022 um 14:57 Uhr

All diese Vorschläge können Ihnen helfen, aber in meinem Fall muss ich ein ob_clean(); vor dem ersten Header (”); weil eine Datei, die ich vor dem Drucken einiger Zeichen einfüge, die die Zip-Datei unter Windows beschädigt hat.

$zip=new ZipArchive();
$zip->open($filename, ZIPARCHIVE::CREATE);
$zip->addFile($file_to_attach,$real_file_name_to_attach);
$zip->close();

ob_clean();
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header('Content-Type: application/x-download');
header('Content-Disposition: attachment; filename="file.zip"');
readfile($filename);
exit;

  • Das hat bei mir funktioniert, alles andere ohne Erfolg versucht.

    – llanato

    27. Juli 2015 um 13:34 Uhr

  • Dieser hat bei mir auch funktioniert. Habe auch alles andere probiert. Dies sollte die akzeptierte Antwort sein. Hinweis: Ich musste nur die Zeile hinzufügen: ob_clean(), damit mein Code funktioniert. Ich habe ein oder zwei Stunden damit verbracht, Zip-Dateien zu bekommen, die geöffnet werden konnten.

    – mikekehrli

    10. Juni 2021 um 21:32 Uhr


Ok, nach langem hin und her habe ich das Problem herausgefunden. Das Problem stammt aus der folgenden Codezeile:

$objZip->addFile($filename,sprintf('/press_photos/%s-%s', $objPhoto->getEntryID(), basename($filename)));

Aus irgendeinem Grund ist die /press_photos/ Ein Teil dieses Pfads für den lokalen (internen) Dateinamen im Zip-Archiv führte dazu, dass Windows dachte, die Zip-Datei sei beschädigt. Nachdem die Zeile so geändert wurde, dass sie wie unten aussieht, öffnete Windows die ZIP-Dateien korrekt. Puh.

$objZip->addFile($filename,sprintf('%s-%s', $objPhoto->getEntryID(), basename($filename)));

Die Verwendung von Sonderzeichen wie Unterstrichen verursacht Probleme, da ZipArchive IBM850-codierte Eintragsnamen erfordert. Siehe Kommentare im Online-PHP-Handbuch: http://www.php.net/manual/en/function.ziparchive-addfile.php#95725 .

  • Ich hatte einen langen ZIP-Dateinamen mit Leerzeichen, Bindestrichen und Datumszeichen. Es stellte sich heraus, dass es gut funktionierte, nachdem ich die Dateinamen in etwas Einfaches wie export.zip geändert hatte.

    – Nathan Hangen

    21. März 2014 um 14:38 Uhr

Benutzeravatar von profitphp
profitphp

Damit hatte ich schon mal Probleme. Versuchen Sie, den Header des Inhaltstyps zu entfernen. Hier ist der Code, den ich mir ausgedacht habe, der in IE und FF funktioniert hat. Beachten Sie die kommentierten Zeilen, hatte die gleichen Probleme mit verschiedenen Kombinationen von denen, die eingeschaltet waren.

header("Cache-Control: public");
header("Pragma: public");
header("Expires: 0");
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header("Cache-Control: public");
//header("Content-Description: File Transfer");
//header("Content-type: application/zip");
header("Content-Disposition: attachment; filename=\"adwords-csv.zip\"");
//header("Content-Transfer-Encoding: binary");
header("Content-length: " . filesize($filename)); 

  • Ich hatte einen langen ZIP-Dateinamen mit Leerzeichen, Bindestrichen und Datumszeichen. Es stellte sich heraus, dass es gut funktionierte, nachdem ich die Dateinamen in etwas Einfaches wie export.zip geändert hatte.

    – Nathan Hangen

    21. März 2014 um 14:38 Uhr

Marks Benutzeravatar
Markieren

Ich habe dieses Problem seit einer Stunde. Nachdem ich 10 verschiedene Lösungen ausprobiert hatte, löste ich es, indem ich sicherstellte, dass das Skript nach der Ausgabe der ZIP-Datei vorhanden ist:

            readfile($zip_name);
            unlink($zip_name);
            **exit();**

  • Dies ist die Lösung, die für mich funktioniert hat, nachdem ich die meisten der oben aufgeführten Dinge ausprobiert hatte

    – Michael Rennison

    8. Dezember 2022 um 15:43 Uhr

1439910cookie-checkPHP ZipArchive in Windows beschädigt

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy