it-swarm.com.de

So erstellen Sie eine Zip-Datei mit PHP und löschen, nachdem der Benutzer es heruntergeladen hat?

Ich muss Bilder von anderen Websites auf meinen Server herunterladen. Erstellen Sie eine Zip-Datei mit diesen Bildern. Startet automatisch den Download der erstellten Zip-Datei. Sobald der Download abgeschlossen ist, sollte die Zip-Datei und die Bilder von meinem Server gelöscht werden.

Anstelle eines automatischen Downloads ist auch ein Download-Link in Ordnung. aber andere Logik bleibt gleich.

15
Joby Joseph

Nun, Sie müssen zuerst die zip-Datei erstellen, indem Sie die Klasse ZipArchive verwenden.

Dann sende :

  • Die rechten Header zeigen an, dass der Browser etwas als Zip herunterladen sollte - sieheheader()- Es gibt ein Beispiel auf der Seite dieses Handbuchs, das helfen sollte
  • Der Inhalt der Zip-Datei mit readfile()

Löschen Sie schließlich die Zip-Datei von Ihrem Server mit unlink() .


Hinweis: Aus Sicherheitsgründen kann es sinnvoll sein, ein PHP - Skript auszuführen, das automatisch (normalerweise von crontab) ausgeführt wird, wodurch die alten Zip-Dateien gelöscht werden Ihr temporäres Verzeichnis.

Dies ist nur für den Fall, dass Ihr normales PHP - Skript unterbrochen ist und die temporäre Datei nicht löscht.

19
Pascal MARTIN
<?php 

Zip('some_directory/','test.Zip');

if(file_exists('test.Zip')){
    //Set Headers:
    header('Pragma: public');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime('test.Zip')) . ' GMT');
    header('Content-Type: application/force-download');
    header('Content-Disposition: inline; filename="test.Zip"');
    header('Content-Transfer-Encoding: binary');
    header('Content-Length: ' . filesize('test.Zip'));
    header('Connection: close');
    readfile('test.Zip');
    exit();
}

if(file_exists('test.Zip')){
    unlink('test.Zip');

}


function Zip($source, $destination)
{
    if (!extension_loaded('Zip') || !file_exists($source)) {
        return false;
    }

    $Zip = new ZipArchive();
    if (!$Zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }

    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', realpath($file));

            if (is_dir($file) === true)
            {
                $Zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $Zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $Zip->addFromString(basename($source), file_get_contents($source));
    }

    return $Zip->close();
}

?>
13
Mahesh Ambig

Gibt es eine Idee, wie viele Zip-Datei-Downloads unterbrochen werden und fortgesetzt werden müssen?

Wenn fortgesetzte Downloads nur einen kleinen Prozentsatz Ihrer Downloads ausmachen, können Sie die ZIP-Datei sofort löschen. Solange Ihr Server die Datei noch an den Client sendet, bleibt sie auf der Festplatte.

Sobald der Server den Dateideskriptor schließt, sinkt der Referenzzähler der Datei auf null und schließlich werden die Blöcke auf der Festplatte freigegeben.

Sie könnten jedoch ziemlich viel Zeit damit verbringen, Zip-Dateien neu zu erstellen, wenn viele Downloads dennoch unterbrochen werden. Nizza billige Optimierung wenn Sie können damit durchkommen.

3
sarnold

So habe ich es in der Vergangenheit geschafft. Bei diesem Code wird davon ausgegangen, dass Sie die Dateien in einen Pfad geschrieben haben, der in der Variablen $path angegeben ist. Möglicherweise müssen Sie einige Berechtigungsprobleme in Ihrer Serverkonfiguration mithilfe von exec von php beheben.

 // write the files you want to Zip up
file_put_contents($path . "/file", $output);

// Zip up the contents
chdir($path);
exec("Zip -r {$name} ./");

$filename = "{$name}.Zip";

header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename='.urlencode($filename));
header('Content-Transfer-Encoding: binary');

readfile($filename);
2
Eric Conner

Aktivieren Sie Ihre php_curl-Erweiterung. (php.ini), Verwenden Sie dann den folgenden Code, um die ZIP-Datei zu erstellen. Erstellen Sie eine Ordnerklasse und verwenden Sie den unten angegebenen Code:

<?php 
    include("class/create_Zip.php");
    $create_Zip     =   new create_Zip();
    //$url_path,$url_path2 you can use your directory path
            $urls = array(
                 '$url_path/file1.pdf',         
                 '$url_path2/files/files2.pdf'
                 ); // file paths 


            $file_name      =   "vin.Zip";   // Zip file default name
            $file_folder    =   Rand(1,1000000000); // folder with random name
            $create_Zip->create_Zip($urls,$file_folder,$file_name);  
            $create_Zip->delete_directory($file_folder);  //delete random folder 

            if(file_exists($file_name)){
             $temp = file_get_contents($file_name);     
             unlink($file_name); 
            }       

            echo $temp;

    ?>

erstellen Sie eine Ordnerklasse und verwenden Sie den unten angegebenen Code:

<?php

    class create_Zip{

        function create_Zip($urls,$file_folder,$file_name){

            header('Content-Type: application/octet-stream'); 
            header('Content-Disposition: attachment; filename='.$file_name); 
            header('Content-Transfer-Encoding: binary');

                $mkdir  =   mkdir($file_folder); 

                $Zip    = new ZipArchive;
                $Zip->open($file_name, ZipArchive::CREATE); 

                foreach ($urls as $url)
                {
                     $path=pathinfo($url);     
                     $path = $file_folder.'/'.$path['basename'];
                     $Zip->addFile($path);     
                     $fileopen = fopen($path, 'w');     
                     $init = curl_init($url);     
                     curl_setopt($init, CURLOPT_FILE, $fileopen);     
                     $data = curl_exec($init);     
                     curl_close($init);     
                     fclose($fileopen); 
                } 

                $Zip->close();


            }

            function delete_directory($dirname) 
            {
                if (is_dir($dirname))
                $dir_handle = opendir($dirname); 
                if (!$dir_handle)
                return false;
                    while($file = readdir($dir_handle))
                    {
                        if ($file != "." && $file != "..") 
                        {
                            if (!is_dir($dirname."/".$file))             
                            unlink($dirname."/".$file);          
                            else            
                            delete_directory($dirname.'/'.$file);           
                        }    
                    }
                closedir($dir_handle);    
                rmdir($dirname);    
                return true; 
            }



    }

    ?>
1

Andere Lösung: Löschen Sie alte Dateien vor der Erstellung einer neuen ZIP-Datei:

    // Delete past Zip files script
    $files = glob('*.Zip'); //get all file names in array
    $currentTime = time(); // get current time
    foreach($files as $file){ // get file from array
        $lastModifiedTime = filemtime($file); // get file creation time

        // get how old is file in hours:
        $timeDiff = abs($currentTime - $lastModifiedTime)/(60*60);

        //check if file was modified before 1 hour:
        if(is_file($file) && $timeDiff > 1)
            unlink($file); //delete file
    }
1
Intacto

Ich suchte dort nach einer ähnlichen Lösung, und nachdem ich die Kommentare gelesen hatte, fand ich diesen Umsatz: Bevor Sie Ihre Zip-Datei in einem speziellen Ordner erstellen (hier 'Zip_files' genannt), löschen Sie alle Zip, die nach Ihrer Einschätzung älter sind als eine angemessene Zeit (ich habe 24 Stunden gebraucht). :

$dossier_Zip='Zip_files';   
    if(is_dir($dossier_Zip))
        {
        $t_Zip=$dossier_Zip.'/*.Zip'; #this allow you to let index.php, .htaccess and other stuffs...
        foreach(glob($t_Zip) as $old_Zip)
            {
            if(is_file($old_Zip) and filemtime($old_Zip)<time()-86400)
                {
                unlink($old_Zip);
                }
            }

        $zipname=$dossier_Zip.'/whatever_you_want_but_dedicated_to_your_user.Zip';
        if(is_file($zipname))
            {
            unlink($zipname); #to avoid mixing 2 archives
            }

        $Zip=new ZipArchive;
#then do your Zip job

Nach 24 Stunden haben Sie nur die letzten Reißverschlüsse erstellt, Benutzer für Benutzer. Es gibt nichts, was Sie daran hindert, manchmal eine Clean by Cron-Aufgabe auszuführen. Das Problem bei der Cron-Aufgabe besteht jedoch darin, dass jemand das Zip-Archiv verwendet, wenn der Cron ausgeführt wird. Dies führt zu einem Fehler. Hier ist der einzige mögliche Fehler, wenn jemand 24h auf DL das Archiv wartet.

0
Romain Bel