簡體   English   中英

如何使用PHP創建ZIP文件並在用戶下載后刪除它?

[英]How to create a ZIP file using PHP and delete it after user downloads it?

我需要從其他網站下載圖像到我的服務器。 使用這些圖像創建ZIP文件。 自動開始下載創建的ZIP文件。 下載完成后,應從我的服務器中刪除ZIP文件和圖像。

而不是自動下載,下載鏈接也沒關系。 但其他邏輯仍然相同。

好吧,你必須首先使用ZipArchive類創建ZipArchive

然后,發送:

  • 正確的標題,指示瀏覽器應該下載一些拉鏈 - 見header() - 該手冊的頁面上有一個例子應該有幫助
  • zip文件的內容,使用readfile()

最后,使用unlink()從服務器中刪除zip文件。


注意:作為安全預防措施,最好讓PHP腳本自動運行(通常由crontab運行 ,這將刪除臨時目錄中的舊zip文件。

這是為了防止您的普通PHP腳本被中斷,並且不會刪除臨時文件。

<?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();
}

?>

其他解決方案:在創建新zip文件之前刪除過去的文件:

    // 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
    }

知道有多少zip文件下載被中斷並需要繼續嗎?

如果繼續下載只占您下載的一小部分,您可以立即刪除zip文件; 只要您的服務器仍在將文件發送到客戶端,它就會保留在磁盤上。

一旦服務器關閉文件描述符,文件的引用計數將降至零,最后將釋放其磁盤上的塊。

但是,如果許多下載中斷,您可能會花費相當多的時間重新創建zip文件。 很好的便宜優化, 如果你可以逃脫它。

以下是我過去的表現。 此代碼假定您已將文件寫入$path變量指定的$path 您可能必須使用php的exec處理服務器配置上的一些權限問題

 // 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);

啟用php_curl擴展名; (php.ini),然后使用下面的代碼創建zip。 創建一個文件夾類並使用下面給出的代碼:

<?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;

    ?>

創建一個文件夾類並使用下面給出的代碼:

<?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; 
            }



    }

    ?>

我去那里尋找類似的解決方案,並在閱讀評論后發現這個營業額:在專用文件夾中創建你的zip文件之前(這里稱為'zip_files',刪除你估計比合理時間早的所有郵政編碼(我花了24小時) :

$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

通過這樣做,在24小時后,您只能按用戶創建最后一個拉鏈。 沒有什么能阻止你有時通過cron任務進行清理,但是cron任務的問題是如果有人在執行cron時使用zip存檔會導致錯誤。 這里唯一可能的錯誤是如果有人等待24小時到存檔的DL。

首先,您從網站下載圖像

然后,你下載的文件你creatae zipfile (偉大的tute)

最后你使用readfile和headers將這個zip文件發送到瀏覽器(參見例1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM