2016-12-18 2 views
0

Ich arbeite derzeit an einem Tool mit PHP (ziemlich Neuling mit dieser Technologie ...), die ZIP-Dateien mit einer Reihe von Dateien erstellen sollte. Dieser Satz von Dateien können sein:PHP - Beschädigter Zip beim Hinzufügen von Zip in Zip

  • Basic-Dateien (Mutliple Formate)
  • Voll Verzeichnisse (wird in die resultierende zip als eine neue ZIP-Datei hinzugefügt werden - ZIP innerhalb der letzten ZIP)

Die Sache ist, dass, wenn die Zip-Dateien einfache Dateien enthält, es ordnungsgemäß heruntergeladen wird, aber wenn die Datei die "Zip-Datei des vollständigen Verzeichnisses" enthält, wird die resultierende ZIP-Datei beschädigt.

Unter dem Code, den ich derzeit verwende (sorry wenn es ein bisschen chaotisch ist, aber ist das erste Mal, dass ich mit PHP arbeiten ...)

function ZipFiles($fileArr,$id) { 
    $destination = "{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/WMDConfigFiles_".$id.".zip"; 
    $valid_files = array(); 

    //if files were passed in... 
    if(is_array($fileArr)) { 
     //cycle through each file 
     foreach($fileArr as $file) {    

      if(is_dir($file)) { 
       //If path is a folder we zip it and put it on $valid_files[] 
       $resultingZipPath = "{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/".basename($file)."_FOLDER.zip"; 
       ZipFolder($file,$resultingZipPath); 
       $valid_files[] = $resultingZipPath ;  
      } 
      else {    
       //If path is not a folder then we make sure the file exists 
       if(file_exists("{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/".$file)) { 
        $valid_files[] = $file;     
       } 
      } 
     } 
    } 
    //if we have good files... 
    if(count($valid_files)) { 
     //create the archive 
     $zip = new ZipArchive(); 
     if($zip->open($destination,ZIPARCHIVE::CREATE) !== true) { 
      return false; 
     } 
     //add the files 
     foreach($valid_files as $file) { 
      $zip->addFile("{$_SERVER['DOCUMENT_ROOT']}/wmdmngtools/tempFiles/".$file,$file); 
     } 

     $zip->close(); 

     return $destination; 
    } 
    else 
    { 
     return ""; 
    } 
} 

function ZipFolder($source, $destination) { 

    // Initialize archive object 
    $folderZip = new ZipArchive(); 
    $folderZip->open($destination, ZipArchive::CREATE | ZipArchive::OVERWRITE); 

    // Create recursive directory iterator 
    /** @var SplFileInfo[] $files */ 
    $files = new RecursiveIteratorIterator(
     new RecursiveDirectoryIterator($source), 
     RecursiveIteratorIterator::LEAVES_ONLY 
    ); 

    foreach ($files as $name => $file) 
    { 
     // Skip directories (they would be added automatically) 
     if (!$file->isDir()) 
     { 
      // Get real and relative path for current file 
      $filePath = $file->getRealPath(); 
      $relativePath = substr($filePath, strlen($source) + 1); 

      // Add current file to archive 
      $folderZip->addFile($filePath, $relativePath); 
     } 
    } 

    // Zip archive will be created only after closing object 
    $folderZip->close(); 

} 

Darauf wir zwei Funktionen sehen:

  • ZipFiles: ist die wichtigste fucntion, die, indem eine Liste/Array (enthält die Liste der Dateien aufgerufen wird, und Ordner, die in die endgültige ZIP-Datei eingefügt werden) und ein ID-Parameter, der einfach verwendet wird, um verschiedene Dateinamen zu erzeugen ... (kann ignoriert werden)
  • ZipFolder: Diese Funktion wird für jeden der Ordner (keine Dateien) aufgerufen die oben genannte Liste/Array, um diesen Ordner zu komprimieren und eine Zip-Datei zu erstellen, um sie in der endgültigen Datei hinzuzufügen. (Bezogen auf das, was ich in How to zip a whole folder using PHP gefunden)

Ich habe viele Dinge ausprobiert, wie in oben Beitrag erwähnt wie alle Dateien zu schließen, oder Vermeidung von Leerreißverschlüsse in der Reißverschluss aber nichts funktionierte ...

Zip inside zip (php)

Vielleicht habe ich etwas vermisst (am wahrscheinlichsten :)) aber mir fehlen Asse, so dass jede Hilfe/Anleitung geschätzt werden würde.

Falls weitere Informationen benötigt werden, lassen Sie es mich bitte wissen und werden es posten.

Vielen Dank im Voraus!

+0

Wer weiß schon, was ich falsch mache? :) –

Antwort

0

Endlich das Problem gefunden. Scheint, dass die Datei korrekt generiert wurde, aber beim Herunterladen von PHP gab es ein Problem, wenn die Größe größer als eine konkrete Zahl war. THis war durch falsche Definition der Nachrichtenlänge auf der Header-Definition:

header("Cache-Control: public"); 
header("Content-Description: File Transfer"); 
header("Content-Length: ".filesize($zippedFile)); 
header("Content-Disposition: attachment; filename=".$zippedFile); 
header("Content-type: application/zip"); 
header("Content-Transfer-Encoding: binary"); 

Auch wenn ich denke, es ist nicht eine richtige Praxis ich den Content-Length-Eintrag entfernt sein kann, und jetzt bekomme ich die richtige Datei trotz der seine Größe.