PHP Dateien auf dem Server zippen und downloaden

M

Mr. Snoot

Gast
Hio,

ich möchte, dass Besucher per Checkbox Dateien, die sie runterladen wollen, auswählen können, und diese dann automatisch vor dem Download gezippt werden.


Jetzt habe öfter die Aussage gelesen, dass PHP Zip-files gar nicht erstellen, sondern nur lesen könne. Andererseits hab ich auch zwei, drei Threads mit Beispielen gefunden, funktionieren tut davon bei mir im Moment aber nur eines so halbwegs.

Das Script sieht im Grund so aus:
PHP:
<?php

  $files = array('1.txt','2.txt');
  
  header('Content-type: application/zip');
  
  passthru('/usr/bin/zip - '.implode(' ',$files));
  
?>
Das klappt eigentlich, allerdings heißt die Datei die dann runtergeladen wird genauso, wie die Datei heißt, die dieses Script enthält (also meinetwegen zip.php).

Die Datei kann man zwar in .zip umbenennen und entpacken, aber es sollte halt gleich ein zip-file erstellt werden.

Ist das möglich?


Was mich auch wundert, in anderen Threads heißt es meisten, man bräuchte eine phpzip.inc.php, damit das mit dem Zippen klappt (dieses Script gibts z.B. hier, es läuft bei mir aber nicht).

Also, genügt mir im Grunde dieses kleine Script was ich da habe (geht ja so halbwegs), oder für was ist diese phpzip.inc.php gedacht?
 
Hallo Mr. Snoot,

wenn du die Datei auf deinem WebSpace speicherst und dann mit einem Header auf die Datei umleitest, sollte es eigentlich funktionieren.

Grüße

krizzel
 
PHP:
<?php
	function download( $file, $speed = 0, $unit = 'kib' )
	{
		$factor = 0;
		switch( strtolower( $unit ) )
		{
			case 'mb' : $factor = 1000000; break; // MB
			case 'mib' : $factor = 1048576; break; // MiB
			case 'b' : $factor = 1; break; // B
			case 'kb' : $factor = 1000; break; // KB
			default : $factor = 1024; // KiB
		}
		
		$bytes = $speed * $factor;
		
		if( !file_exists( $file ) ) return false;
		
		$filename = basename( $file );
		$filesize = filesize( $file );
		
		header( 'Content-Type: application/octet-stream' );
		header( 'Content-Disposition: attachment;filename="'.$filename.'"' );
		header( 'Content-Length: '.$filesize );
		
		if( $bytes == 0 ) readfile( $file );
		else
		{
			$fh = fopen( $file, 'r' );
			
			if( !$fh ) return false;
			
			set_time_limit( 0 );
			
			while( !feof( $fh ) )
			{
				echo fread( $fh, $bytes );
				flush();
				if( !feof( $fh ) ) sleep( 1 );
			}
			
			fclose( $fh );
		}
		
		return true;
	}
?>
du kannst ja einen zusätzlichen parameter mit in die liste einfügen und diese dann bei $filename einsetzen.
 
Hast du es schonmal mit dem Beispiel von Jonathan Baltazar versucht:
PHP:
<?php 
$file = tempnam("tmp", "zip"); 
     
$zip = new ZipArchive(); 
 
// Zip will open and overwrite the file, rather than try to read it. 
$zip->open($file, ZipArchive::OVERWRITE); 
 
$zip->close(); 
 
// Stream the file to the client 
header("Content-Type: application/zip"); 
header("Content-Length: " . filesize($file)); 
header("Content-Disposition: attachment; filename=\"a_zip_file.zip\""); 
readfile($file); 
 
unlink($file); 
?>
 
Nach etlichem Rumprobieren hab ich jetzt ein Script gefunden, das bei mir funktioniert:
PHP:
<?php

// Startet den Buffer, sodass keine Header-Fehlermeldungen entstehen.
ob_start();

// Läd die Zip-Library
// http://frankyonline.de/wp-content/uploads/2008/08/ziplib-2003-04-14.zip
require("zip.lib.php");

// Erstellt eine neue Zipdatei
$zipfile = new zipfile("archiv.zip");


// Fügt die Datei in die Zipdatei ein.
$zipfile->addFileAndRead($datei);


// Gibt die Zip-Datei aus.
echo $zipfile->file();
?>
Bei so gut wie allen anderen kommt entweder eine Fehlermeldung oder es tut sich einfach nichts.

Danke an alle :)
 
Zurück
Oben