# Zip Dateien mit PHP erstellen - Archive lassen sich mit WinZip nicht öffnen



## diggity (30. Juni 2007)

Hallo leute,

Ich hoffe ihr könnt mir da weiter helfen, ich bin nämlich am Ende. 
Ich erstelle mit PHP ZIP dateien, die mehere Dateien beinhalten. Dazu habe ich mehere Klassen getestet und verwende nun diese, die am besten meinen Anforderungen entspricht. 

Nun tritt aber folgendes Phänomen auf: Mit WinRAR lassen sich die generierten Archive problemlos öffnen, mit WinZip zB hingegen bekomme ich eine Meldung, die in etwa "anfang des zentralverzeischnisses nicht gefunden zip datei beschädigt" lautet.

An der Klasse die ich zum Erstellen benutze liegts nicht, ich habs auch shcon mit anderen Klassen versucht, immer das Selbe. 

An was kann es dann liegen? die zlib Version kanns auch nicht sein, habs mit der neuesten Version versucht und mit einer älteren. 

2. Phänomen: Bei dieser Zipfunktion rufe ich über den Browser ein Script auf, das mir die Dateien dann in ein entsprechendes Archiv packt bzw packen soll und mir diese anschließend schickt (die Datei wird an den Client gesendet sodass dieser sie speichern kann). 
Im Firefox packt er mir die Dateien richtig in die zip, im IE hingegen landet in der zip Datei nur 1 Datei, die gleich heißt wie die zu downloadende zip Datei selbst, allerdings ohne Endung... total komisch. 
Wie kann das mit dem Browser zusammenhängen was er IM Script (also serverseitig) in die Datei packt?! 
Offline funktioniert dieser Zipvorgang allerdings auch mit dem IE (ich habe eine lokale Entwicklungsumgebung und einen Produktivserver), deshalb vermute ich dass am Server irgendwas falsch eingestellt ist.
Nur was kann das sein?

Die generierten Datein des lokalen Servers lassen sich allerdings auch nicht mit Winzip öffnen... was läuft hier falsch?

Ich hoffe ihr könnt mir da weiterhelfen, wär echt super


----------



## saftmeister (30. Juni 2007)

Da ich nicht weiß, wie dein Script aussieht, hier nur ein Link zu einem Beitrag von Kristian Köhntopp: http://www.php-faq.de/q/q-datei-download.html


----------



## diggity (30. Juni 2007)

Ich glaube nicht das der Download schuld ist, weil ja die Datei mit Winrar auf geht und mit Winzip nicht, und die Datei am Produktivserver mit dem IE schon falsch generiert wird. Es kann also nur am Server bzw an dessen Einstellungen liegen - meiner Meinung nach. 

Den Download habe ich so gemacht:

```
public function forceDownload($archiveName) {
        $headerInfo = '';
        
        if(ini_get('zlib.output_compression')) {
            ini_set('zlib.output_compression', 'Off');
        }

        // Security checks
        if( $archiveName == "" ) {
            echo "download file nicht angegeben";
            exit;
        }
        elseif ( ! file_exists( $archiveName ) ) {
            echo "datei nicht gefunden";
            exit;
        }

        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private",false);
        header("Content-Type: application/zip");
        header("Content-Disposition: attachment; filename=".basename($archiveName).";" );
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($archiveName));
        readfile("$archiveName");
        
     }
```


----------



## saftmeister (30. Juni 2007)

Versuch ma als Content-Type das hier zu senden:


```
header("Content-Type: application/octet-stream");
```

Grüße


----------



## diggity (2. Juli 2007)

Super, besten Dank für diesen Hinweis. 
Jetzt funktioniert der Download im IE auch, dh es werden auch hier die Dateien richtig reingepackt. 

Allerdings lassen sich die generierten Archive noch immer nicht überall öffnen, nur mit WinRAR gehen sie auf.


----------



## saftmeister (2. Juli 2007)

Welche Klasse/Package verwendest du denn zum zusammenschnüren? Evtl liegt der Hund ja dort begraben.


----------



## diggity (2. Juli 2007)

Ich verwende dazu diese Klasse: http://www.phpclasses.org/browse/package/2322.html

Hab allerdings auch schon eine andere probiert, genau das selbe Problem. 


```
<?php

/**
* Class to dynamically create a zip file (archive)
*
* @author Rochak Chauhan
*/

class createZip  {  

    public $compressedData = array();
    public $centralDirectory = array(); // central directory   
    public $endOfCentralDirectory = "\x50\x4b\x05\x06\x00\x00\x00\x00"; //end of Central directory record
    public $oldOffset = 0;

    /**
     * Function to create the directory where the file(s) will be unzipped
     *
     * @param $directoryName string
     *
     */
    
    public function addDirectory($directoryName) {
        $directoryName = str_replace("\\", "/", $directoryName);  

        $feedArrayRow = "\x50\x4b\x03\x04";
        $feedArrayRow .= "\x0a\x00";    
        $feedArrayRow .= "\x00\x00";    
        $feedArrayRow .= "\x00\x00";    
        $feedArrayRow .= "\x00\x00\x00\x00";

        $feedArrayRow .= pack("V",0);
        $feedArrayRow .= pack("V",0);
        $feedArrayRow .= pack("V",0);
        $feedArrayRow .= pack("v", strlen($directoryName) );
        $feedArrayRow .= pack("v", 0 );
        $feedArrayRow .= $directoryName;  

        $feedArrayRow .= pack("V",0);
        $feedArrayRow .= pack("V",0);
        $feedArrayRow .= pack("V",0);

        $this -> compressedData[] = $feedArrayRow;
        
        $newOffset = strlen(implode("", $this->compressedData));

        $addCentralRecord = "\x50\x4b\x01\x02";
        $addCentralRecord .="\x00\x00";    
        $addCentralRecord .="\x0a\x00";    
        $addCentralRecord .="\x00\x00";    
        $addCentralRecord .="\x00\x00";    
        $addCentralRecord .="\x00\x00\x00\x00";
        $addCentralRecord .= pack("V",0);
        $addCentralRecord .= pack("V",0);
        $addCentralRecord .= pack("V",0);
        $addCentralRecord .= pack("v", strlen($directoryName) );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("v", 0 );
        $ext = "\x00\x00\x10\x00";
        $ext = "\xff\xff\xff\xff";  
        $addCentralRecord .= pack("V", 16 );

        $addCentralRecord .= pack("V", $this -> oldOffset );
        $this -> oldOffset = $newOffset;

        $addCentralRecord .= $directoryName;  

        $this -> centralDirectory[] = $addCentralRecord;  
    }    
    
    /**
     * Function to add file(s) to the specified directory in the archive
     *
     * @param $directoryName string
     *
     */
    
    public function addFile($data, $directoryName)   {

        $directoryName = str_replace("\\", "/", $directoryName);  
    
        $feedArrayRow = "\x50\x4b\x03\x04";
        $feedArrayRow .= "\x14\x00";    
        $feedArrayRow .= "\x00\x00";    
        $feedArrayRow .= "\x08\x00";    
        $feedArrayRow .= "\x00\x00\x00\x00";

        $uncompressedLength = strlen($data);  
        $compression = crc32($data);  
        $gzCompressedData = gzcompress($data);  
        $gzCompressedData = substr( substr($gzCompressedData, 0, strlen($gzCompressedData) - 4), 2);
        $compressedLength = strlen($gzCompressedData);  
        $feedArrayRow .= pack("V",$compression);
        $feedArrayRow .= pack("V",$compressedLength);
        $feedArrayRow .= pack("V",$uncompressedLength);
        $feedArrayRow .= pack("v", strlen($directoryName) );
        $feedArrayRow .= pack("v", 0 );
        $feedArrayRow .= $directoryName;  

        $feedArrayRow .= $gzCompressedData;  

        $feedArrayRow .= pack("V",$compression);
        $feedArrayRow .= pack("V",$compressedLength);
        $feedArrayRow .= pack("V",$uncompressedLength);

        $this -> compressedData[] = $feedArrayRow;

        $newOffset = strlen(implode("", $this->compressedData));

        $addCentralRecord = "\x50\x4b\x01\x02";
        $addCentralRecord .="\x00\x00";    
        $addCentralRecord .="\x14\x00";    
        $addCentralRecord .="\x00\x00";    
        $addCentralRecord .="\x08\x00";    
        $addCentralRecord .="\x00\x00\x00\x00";
        $addCentralRecord .= pack("V",$compression);
        $addCentralRecord .= pack("V",$compressedLength);
        $addCentralRecord .= pack("V",$uncompressedLength);
        $addCentralRecord .= pack("v", strlen($directoryName) );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("v", 0 );
        $addCentralRecord .= pack("V", 32 );

        $addCentralRecord .= pack("V", $this -> oldOffset );
        $this -> oldOffset = $newOffset;

        $addCentralRecord .= $directoryName;  

        $this -> centralDirectory[] = $addCentralRecord;  
    }

    /**
     * Fucntion to return the zip file
     *
     * @return zipfile (archive)
     */

    public function getZippedfile() {

        $data = implode("", $this -> compressedData);  
        $controlDirectory = implode("", $this -> centralDirectory);  

        return   
            $data.  
            $controlDirectory.  
            $this -> endOfCentralDirectory.  
            pack("v", sizeof($this -> centralDirectory)).     
            pack("v", sizeof($this -> centralDirectory)).     
            pack("V", strlen($controlDirectory)).             
            pack("V", strlen($data)).                
            "\x00\x00";                             
    }

    /**
     *
     * Function to force the download of the archive as soon as it is created
     *
     * @param archiveName string - name of the created archive file
     */

    public function forceDownload($archiveName) {
        $headerInfo = '';
        
        if(ini_get('zlib.output_compression')) {
            ini_set('zlib.output_compression', 'Off');
        }

        // Security checks
        if( $archiveName == "" ) {
            echo "download file nicht angegeben";
            exit;
        }
        elseif ( ! file_exists( $archiveName ) ) {
            echo "datei nicht gefunden";
            exit;
        }

        header("Pragma: public");
        header("Expires: 0");
        header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private",false);
//        header("Content-Type: application/zip");
		header("Content-Type: application/octet-stream");  
        header("Content-Disposition: attachment; filename=".basename($archiveName).";" );
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: ".filesize($archiveName));
        readfile("$archiveName");
        
     }

}
?>
```


----------



## saftmeister (3. Juli 2007)

Schon PEAR::Archive_ZIP probiert? Damit hatte ich eigentlich nie Probleme.


----------

