mediengestalter.info
FAQ :: Mitgliederliste :: MGi Team

Willkommen auf dem Portal für Mediengestalter

Aktuelles Datum und Uhrzeit: Fr 29.03.2024 15:52 Benutzername: Passwort: Auto-Login

Thema: PHP Verzeichnis online komprimieren vom 30.05.2006


Neues Thema eröffnen   Neue Antwort erstellen MGi Foren-Übersicht -> Programmierung -> PHP Verzeichnis online komprimieren
Seite: 1, 2  Weiter
Autor Nachricht
marcusm
Threadersteller

Dabei seit: 06.05.2002
Ort: europa
Alter: 45
Geschlecht: Männlich
Verfasst Di 30.05.2006 22:33
Titel

PHP Verzeichnis online komprimieren

Antworten mit Zitat Zum Seitenanfang

N'Abend Mitstreiter,

habe gerade folgendes vor: Ein auf dem Webserver bestehendes Verzeichnis inkl. aller Unterverzeichnisse und Dateien komprimieren und in ein anderes Verzeichnis auf dem Webserver speichern. Würde das gerne mit PHP lösen, hat jemand einen Tipp für mich? Habe bereits mit dem Script unten experimentiert, bekomme aber lediglich ein "beschädigtes" Zip-File dabei heraus...

Code:
<?php
class zipfile
{
    var $datasec = array(); // array to store compressed data
    var $ctrl_dir = array(); // central directory   
    var $eof_ctrl_dir = "x50x4bx05x06x00x00x00x00"; //end of Central directory record
    var $old_offset = 0;
   
    function add_dir($name){
        $name = str_replace("\\", "/", $name);
      
        $fr = "x50x4bx03x04";
        $fr .= "x0ax00";    // ver needed to extract
        $fr .= "x00x00";    // gen purpose bit flag
        $fr .= "x00x00";    // compression method
        $fr .= "x00x00x00x00"; // last mod time and date
      
        $fr .= pack("V",0); // crc32
        $fr .= pack("V",0); //compressed filesize
        $fr .= pack("V",0); //uncompressed filesize
        $fr .= pack("v", strlen($name) ); //length of pathname
        $fr .= pack("v", 0 ); //extra field length
        $fr .= $name; 
        // end of "local file header" segment
      
        // no "file data" segment for path
      
        // "data descriptor" segment (optional but necessary if archive is not served as file)
        $fr .= pack("V",$crc); //crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize
      
        // add this entry to array
        $this -> datasec[] = $fr;
      
        $new_offset = strlen(implode("", $this->datasec));
      
        // ext. file attributes mirrors MS-DOS directory attr byte, detailed
        // at http://support.microsoft.com/support/kb/articles/Q125/0/19.asp
      
        // now add to central record
        $cdrec = "x50x4bx01x02";
        $cdrec .="x00x00";    // version made by
        $cdrec .="x0ax00";    // version needed to extract
        $cdrec .="x00x00";    // gen purpose bit flag
        $cdrec .="x00x00";    // compression method
        $cdrec .="x00x00x00x00"; // last mod time & date
        $cdrec .= pack("V",0); // crc32
        $cdrec .= pack("V",0); //compressed filesize
        $cdrec .= pack("V",0); //uncompressed filesize
        $cdrec .= pack("v", strlen($name) ); //length of filename
        $cdrec .= pack("v", 0 ); //extra field length   
        $cdrec .= pack("v", 0 ); //file comment length
        $cdrec .= pack("v", 0 ); //disk number start
        $cdrec .= pack("v", 0 ); //internal file attributes
        $ext = "x00x00x10x00";
        $ext = "xffxffxffxff"; 
        $cdrec .= pack("V", 16 ); //external file attributes  - 'directory' bit set
      
        $cdrec .= pack("V", $this -> old_offset ); //relative offset of local header
        $this -> old_offset = $new_offset;
      
        $cdrec .= $name; 
        // optional extra field, file comment goes here
        // save to array
        $this -> ctrl_dir[] = $cdrec;
   }


    function add_file($data, $name){
        $name = str_replace("", "/", $name); 
        //$name = str_replace("", "", $name);
      
        $fr = "x50x4bx03x04";
        $fr .= "x14x00";    // ver needed to extract
        $fr .= "x00x00";    // gen purpose bit flag
        $fr .= "x08x00";    // compression method
        $fr .= "x00x00x00x00"; // last mod time and date
      
        $unc_len = strlen($data); 
        $crc = crc32($data); 
        $zdata = gzcompress($data); 
        $zdata = substr( substr($zdata, 0, strlen($zdata) - 4), 2); // fix crc bug
        $c_len = strlen($zdata); 
        $fr .= pack("V",$crc); // crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize
        $fr .= pack("v", strlen($name) ); //length of filename
        $fr .= pack("v", 0 ); //extra field length
        $fr .= $name; 
        // end of "local file header" segment
       
        // "file data" segment
        $fr .= $zdata; 
      
        // "data descriptor" segment (optional but necessary if archive is not served as file)
        $fr .= pack("V",$crc); //crc32
        $fr .= pack("V",$c_len); //compressed filesize
        $fr .= pack("V",$unc_len); //uncompressed filesize
      
        // add this entry to array
        $this -> datasec[] = $fr;
      
        $new_offset = strlen(implode("", $this->datasec));
      
        // now add to central directory record
        $cdrec = "x50x4bx01x02";
        $cdrec .="x00x00";    // version made by
        $cdrec .="x14x00";    // version needed to extract
        $cdrec .="x00x00";    // gen purpose bit flag
        $cdrec .="x08x00";    // compression method
        $cdrec .="x00x00x00x00"; // last mod time & date
        $cdrec .= pack("V",$crc); // crc32
        $cdrec .= pack("V",$c_len); //compressed filesize
        $cdrec .= pack("V",$unc_len); //uncompressed filesize
        $cdrec .= pack("v", strlen($name) ); //length of filename
        $cdrec .= pack("v", 0 ); //extra field length   
        $cdrec .= pack("v", 0 ); //file comment length
        $cdrec .= pack("v", 0 ); //disk number start
        $cdrec .= pack("v", 0 ); //internal file attributes
        $cdrec .= pack("V", 32 ); //external file attributes - 'archive' bit set
      
        $cdrec .= pack("V", $this -> old_offset ); //relative offset of local header
      // echo "old offset is ".$this->old_offset.", new offset is $new_offset<br>";
        $this -> old_offset = $new_offset;
      
        $cdrec .= $name; 
        // optional extra field, file comment goes here
        // save to central directory
        $this -> ctrl_dir[] = $cdrec; 
    }

    function file() { // dump out file   
        $data = implode("", $this -> datasec); 
        $ctrldir = implode("", $this -> ctrl_dir); 
      
        return   
            $data. 
            $ctrldir. 
            $this -> eof_ctrl_dir. 
            pack("v", sizeof($this -> ctrl_dir)).   // total # of entries "on this disk"
            pack("v", sizeof($this -> ctrl_dir)).   // total # of entries overall
            pack("V", strlen($ctrldir)).            // size of central dir
            pack("V", strlen($data)).               // offset to start of central dir
            "x00x00";                                // .zip file comment length
    }
}
?>
<?php
$zipfile = new zipfile();

// add the subdirectory ... important!
$zipfile -> add_dir("dir/");

// add the binary data stored in the string 'filedata'
//$filedata = "(read your file into $filedata)";

$fp=fopen("test.txt",'r');

$filedata=fread($fp, filesize("test.txt"));
$zipfile -> add_file($filedata, "dir/test.txt");

// the next three lines force an immediate download of the zip file:
header("Content-type: application/octet-stream");
header("Content-disposition: attachment; filename=output.zip");
echo $zipfile -> file();

// OR instead of doing that, you can write out the file to the loca disk like this:
$filename = "output.zip";
$fd = fopen ($filename, "wb");
$out = fwrite ($fd, $zipfile -> file());
fclose ($fd);

// then offer it to the user to download:
echo '<a href="output.zip">Click here to download the new zip file.</a>';
?>
  View user's profile Private Nachricht senden
Sarky

Dabei seit: 29.06.2002
Ort: Düsseldorf
Alter: 42
Geschlecht: Männlich
Verfasst Mi 31.05.2006 07:14
Titel

Antworten mit Zitat Zum Seitenanfang

Wo hast Du das Script her? Hast Du schon PEAR::Archive_Zip probiert (auch wenn es noch Unstable Beta ist)?
http://pear.php.net/package/Archive_Zip

Ansonsten würde ich gar nicht erst groß versuchen hier in PHP eine native Funktion zur Erstellung von ZIP-Files zu erstellen sondern mir lieber die Zeit sparen und per System-Call ein Kommandozeilen-Tool verwenden, eventuell noch eine OS-Weiche je nachdem ob das PHP-Script unter Windows oder Linux läuft.
  View user's profile Private Nachricht senden
Anzeige
Anzeige
WurstOderWas

Dabei seit: 26.03.2003
Ort: -
Alter: 43
Geschlecht: Männlich
Verfasst Mi 31.05.2006 07:16
Titel

Antworten mit Zitat Zum Seitenanfang

kannst du nicht einfach mit exec auf die linux-konsole zugreifen...
ist denk ich mal wesentlich einfacher und vor allem schneller!
  View user's profile Private Nachricht senden
tacker

Dabei seit: 22.03.2002
Ort: Trondheim, Norwegen
Alter: 43
Geschlecht: Männlich
Verfasst Mi 31.05.2006 10:34
Titel

Antworten mit Zitat Zum Seitenanfang

Die Kommando-Zeilen-Version dürfte tatsächlich am performantesten sein.
Warum willst Du das überhaupt in PHP machen?

Die performanteste Version unter PHP ist das mittels PECL ZIP zu machen: http://pecl.php.net/package/zip
  View user's profile Private Nachricht senden Website dieses Benutzers besuchen
WurstOderWas

Dabei seit: 26.03.2003
Ort: -
Alter: 43
Geschlecht: Männlich
Verfasst Mi 31.05.2006 11:36
Titel

Antworten mit Zitat Zum Seitenanfang

und ich sach noch... *Thumbs up!*
  View user's profile Private Nachricht senden
marcusm
Threadersteller

Dabei seit: 06.05.2002
Ort: europa
Alter: 45
Geschlecht: Männlich
Verfasst Do 05.04.2007 11:54
Titel

Antworten mit Zitat Zum Seitenanfang

Tag zusammen,

habe mich zwischezeitlich weiter mit diesem Thema befasst und kann aktuell wunderbar zip-Archive erzeugen.
Dazu benutzte ich diese Klasse pclzip.
Was allerdings immer noch scheitert, ist das entpacken des Archivs.

Ziel ist es ein Media-Verzeichnis zu sichern, das zwei Verzeichnisse ("Image","Pdf") enthält, in diesen beiden Ordnern liegt dann jeweils ein Pic und eine PDF-Datei.

So packe ich:
Code:
<?php
include_once("pclzip.lib.php");

$mein_zip_file="media.zip";
$verzeichnisse=array("media/Image/", "media/Pdf/");

$archive = new PclZip($mein_zip_file);
$archive->create($verzeichnisse);
?>


Erzeugt mir problemlos ein Datei "media.zip", welche auf der localen Maschine sorgenfrei entpackt werden kann.

Zu entpacken versuche ich so:
Code:
<?php
include_once("pclzip.lib.php");

$mein_zip_file="media.zip";
$archive = new PclZip($mein_zip_file);
$list = $archive->extract();
//$list = $archive->extract(PCLZIP_OPT_SET_CHMOD, 0777);

print_r($list);
?>


Habe bereits versucht mit der auskommentierten Zeile zu arbeiten, ohne Erfolg.
Das Script erzeugt mir online ein Verzeichnis mit dem Namen "media" was soweit richtig ist, allerdings nicht mehr
die eigentlich in ihm liegenden Verzeichnisse und Dateien.
Die Ausgabe des Arrays gibt mir einen Status zurück, welcher höchstwahrscheinlich Ursache des Problems ist:
Code:
Array
(
    [0] => Array
        (
            [filename] => .//media/Image/
            [stored_filename] => media/Image/
            [size] => 0
            [compressed_size] => 0
            [mtime] => 1175686184
            [comment] =>
            [folder] => 1
            [index] => 0
            [status] => path_creation_fail
        )
    [1] => Array
        (
            [filename] => .//media/Image/Dodge-Challenger.jpg
            [stored_filename] => media/Image/Dodge-Challenger.jpg
            [size] => 49458
            [compressed_size] => 47153
            [mtime] => 1175686182
            [comment] =>
            [folder] =>
            [index] => 1
            [status] => path_creation_fail
        )
    [2] => Array
        (
            [filename] => .//media/Pdf/
            [stored_filename] => media/Pdf/
            [size] => 0
            [compressed_size] => 0
            [mtime] => 1175686252
            [comment] =>
            [folder] => 1
            [index] => 3
            [status] => path_creation_fail
        )
    [3] => Array
        (
            [filename] => .//media/Pdf/rauchpause.pdf
            [stored_filename] => media/Pdf/rauchpause.pdf
            [size] => 40949
            [compressed_size] => 38939
            [mtime] => 1175686254
            [comment] =>
            [folder] =>
            [index] => 4
            [status] => path_creation_fail
        )
)


Vor dem Entpacken des Archivs benenne ich das ursprünglich "media"-Verzeichnis natürlich um.
Das Script zum packen/entpacken sowie das Verzeichnis "media" liegen im httpdocs-Verzeichnis welches einen chmod 0777 hat.

Kann jemand weiter helfen? Danke!
marcusm
  View user's profile Private Nachricht senden
schachbrett

Dabei seit: 11.10.2006
Ort: Köln
Alter: -
Geschlecht: Männlich
Verfasst Do 05.04.2007 12:36
Titel

Antworten mit Zitat Zum Seitenanfang

tacker hat geschrieben:
Die Kommando-Zeilen-Version dürfte tatsächlich am performantesten sein.


Warum eigentlich??? Sind die PHP eigenen Zip-Algorithmen denn so schlecht implementiert???


Zuletzt bearbeitet von schachbrett am Do 05.04.2007 15:41, insgesamt 1-mal bearbeitet
  View user's profile Private Nachricht senden
marcusm
Threadersteller

Dabei seit: 06.05.2002
Ort: europa
Alter: 45
Geschlecht: Männlich
Verfasst Do 05.04.2007 13:00
Titel

Antworten mit Zitat Zum Seitenanfang

Das ganze via exec() also als Kommando-Zeilen-Version zu realisieren schließt sich aus,
da ich scheinbar nicht genügend Rechte besitze um ein externes Programm zu starten....
  View user's profile Private Nachricht senden
 
Ähnliche Themen [PHP] Verzeichnis auslesen?
Verzeichnis Probleme in PHP
PHP.ini für bestimmtes Verzeichnis
XML-Verzeichnis in HTML ändern
ASP Include und übergeordnetes Verzeichnis
verzeichnis für jeden user
Neues Thema eröffnen   Neue Antwort erstellen Seite: 1, 2  Weiter
MGi Foren-Übersicht -> Programmierung


Du kannst keine Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum nicht antworten.
Du kannst an Umfragen in diesem Forum nicht mitmachen.