Fortschrittsanzeige für Erstellen von Zip - Archiv

mgk89

Grünschnabel
Hallo,

mit folgendem PHP Script wird ein Zip Archiv mit Bildern erstellt. Je nach Auswahl des Foto Albums kann das mit >100 Bildern einige Zeit dauern. Das funktioniert nun auch soweit.

Ideal wäre jetzt eine Art Fortschrittsbalken um zu sehen, wie weit die Erstellung des Zip Archivs ist.

Folgender Code erstellt das Zip Archiv:

Code:
function create_zip($files = array(),$destination = '',$overwrite = true) {
    //if the zip file already exists and overwrite is false, return false
    if(file_exists($destination) && !$overwrite) { return false; }
    //vars
    $valid_files = array();
    //if files were passed in...
    if(is_array($files)) {
        //cycle through each file
        foreach($files as $file) {
            //make sure the file exists
            if(file_exists($file)) {
                $valid_files[] = $file;
            }
        }
    }
    //if we have good files...
    if(count($valid_files)) {
        //create the archive
        $zip = new ZipArchive();
        if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
            return false;
        }
        //add the files
        foreach($valid_files as $file) {
        $explode = explode ("/", $file);
        $zahl = count($explode);
        $filename = $explode[$zahl-1];
            $zip->addFile($file,$filename);

        }
        //debug
        //echo 'The zip archive contains ',$zip->numFiles,' files with a status of ',$zip->status;
       
        //close the zip -- done!
        $zip->close();
       
        //check to make sure the file exists
        return file_exists($destination);
    }
    else
    {
        return false;
    }

$result = create_zip($files_to_zip,$album_zip);

Nun kenne ich mich leider mit AJAX nicht gut aus, aber wäre das damit realisierbar?

Ich hätte gerne eine index.phpmit der per click das Erstellen des Archivs (zip.php) starten kann und den Fortschritt sieht. Es müsste eigentlich nach jedem erfolgreich hinzugefügten Bild in das Archiv ein Counter nach oben gehen und der Wert dann an die index.php zurückgegeben werden, damit dann der Fortschrittsbalken angepasst werden kann. Dann könnte der Balken bspw. bei 100 Bildern nach Bild 1 die Breite (1/100) pixel, nach Bild 2 (2/100) pixel, etc. haben?

Bin sehr dankbar für eure Hilfe!
 
Ich habe gerade nicht so viel Zeit, werde Dir aber später noch eine Antwort darauf geben. Vorerst habe ich aber mal Dein Skript verbessert, weil es mir einfach in den Fingern gezuckt hat:
PHP:
function create_zip( $destination, array $files = array(), $overwrite = true ) {
    $destination = realpath( $destination );
   
    if ( $destination === false && !$overwrite ) {
        return false;
    }
   
    array_walk( $files, function ( &$file ) {
        $file = realpath( $file );
    });
   
    $files = array_filter( $files );
   
    if ( empty( $files ) ) {
        return false;
    }
   
    $zip = new ZipArchive;
    $ret = $zip->open( $destination, ( $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE ) );
   
    if ( $ret !== true ) {
        return false;
    }
   
    foreach ( $files as $file ) {
        $filename = array_pop( explode( '/', $file ) );
        $zip->addFile( $file, $filename );
    }
   
    $zip->close();
   
    return file_exists( $destination );
}
 
hi,

danke für die Antwort & die Korrektur. Bin schon gespannt auf deine Antwort bzgl. der Fortschritts-Anzeige.

Danke und schöne Grüße
 
Also ich würde es wie folgt lösen: beim Generieren des Formulars definierst Du einen Hash-Wert, der den Prozess kennzeichnet. Diesen speicherst Du in einem versteckten Feld des Formulars, so dass er beim Absenden mit übermittelt wird. Diesen Hash-Wert nutzt dann einerseits das Skript, welches das Archiv erstellt, um dort Informationen über den Fortschritt zu speichern, andererseits gibt es noch ein Skript, welches die Werte des Fortschritts speichern. Somit kannst Du immer abfragen, wieweit der Prozess schon ist.
PHP:
$file = realpath( $_GET["hash"] );

if ( $file === false ) {
    header( "HTTP/1.1 404 Not Found" );
    exit;
}

$content = trim( file_get_contents( $file ) );

if ( empty( $content ) ) {
    header( "HTTP/1.1 404 Not Found" );
    exit;
}

header( "Content-Type: application/json" );
header( "Content-Length: " . strlen( $content ) );
echo $content;
PHP:
function create_zip( $destination, array $files = array(), $overwrite = true, Closure $callback = null ) {
    $destination = realpath( $destination );
    $callback    = $callback === null ? function () {} : $callback;
   
    if ( $destination === false && !$overwrite ) {
        $callback(array( "error" => "insufficient parameter" ));
        return false;
    }
   
    array_walk( $files, function ( &$file ) {
        $file = realpath( $file );
    });
   
    $files = array_filter( $files );
   
    if ( empty( $files ) ) {
        $callback(array( "error" => "no valid files" ));
        return false;
    }
   
    $zip = new ZipArchive;
    $callback(array( "status" => "create archive", "number" => count($files), "done" => 0 ));
    $ret = $zip->open( $destination, ( $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE ) );
   
    if ( $ret !== true ) {
        $callback(array( "error" => "failed to open archive" ));
        return false;
    }
   
    $done = 0;
   
    foreach ( $files as $file ) {
        $filename = array_pop( explode( '/', $file ) );
        $zip->addFile( $file, $filename );
        $callback(array( "status" => "add file", "number" => count($files), "done" => ++$done ));
    }
   
    $zip->close();
   
    return file_exists( $destination );
}
PHP:
create_archive( $destination, $files, $overwrite, function ($opts) {
  file_put_contents( $_POST[ "hash" ], json_encode( $opts ));
});
 

Neue Beiträge

Zurück