簡體   English   中英

使用 php 壓縮和下載文件

[英]zip and download files using php

我正在嘗試從名為“上傳”的文件夾中壓縮和下載文件。 正在下載 Zip 文件,但我無法打開(提取)它。 我收到類似“存檔格式未知或已損壞”的錯誤消息。

我找到了以下代碼來壓縮文件夾。

<?php
    $files = "upload/".array('Dear GP.docx','ecommerce.doc');
    $zipname = 'filename.zip';
    $zip = new ZipArchive;
    $zip->open($zipname, ZipArchive::CREATE);
    foreach ($files as $file) {
      $zip->addFile($file);
    }
    $zip->close();
    header('Content-Type: application/zip');
    header('Content-disposition: attachment; filename=filename.zip');
    header('Content-Length: ' . filesize($zipfilename));
    readfile($zipname);
?>

感謝您的回答。

<?php
    $files = array('Dear GP.docx','ecommerce.doc');

    # create new zip opbject
    $zip = new ZipArchive();

    # create a temp file & open it
    $tmp_file = tempnam('.','');
    $zip->open($tmp_file, ZipArchive::CREATE);

    # loop through each file
    foreach($files as $file){

        # download file
        $download_file = file_get_contents($file);

        #add it to the zip
        $zip->addFromString(basename($file),$download_file);

    }

    # close zip
    $zip->close();

    # send the file to the browser as a download
    header('Content-disposition: attachment; filename=Resumes.zip');
    header('Content-type: application/zip');
    readfile($tmp_file);
 ?>

我在我的 mac(本地主機)上花了 6 個多小時來下載這個 zip 文件 - 盡管文件正在下載,但我無法解壓縮它們(獲取 cpgz 文件)。 顯然,堆棧溢出中提到的所有解決方案(圍繞 zip 文件下載的各種問題)都沒有奏效。 最后,經過反復試驗,我發現以下代碼有效:

之前回答的人都沒有談到 ob_start() 以及您應該把它放在哪里。 無論如何,僅此而已不是答案-您也需要使用 ob_start() 上方的那三行。

$file=$zippath.$filename;
if (headers_sent()) {
    echo 'HTTP header already sent';
} else {
    if (!is_file($file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
        echo 'File not found';
    } else if (!is_readable($file)) {
        header($_SERVER['SERVER_PROTOCOL'].' 403 Forbidden');
        echo 'File not readable';
    } else {
        while (ob_get_level()) {
            ob_end_clean();
        }
       ob_start();
       header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
       header("Content-Type: application/zip");
       header("Content-Transfer-Encoding: Binary");
       header("Content-Length: ".filesize($file));
       header('Pragma: no-cache');
       header("Content-Disposition: attachment; filename=\"".basename($file)."\"");
       ob_flush();
       ob_clean();
       readfile($file);
       exit;
   }
}

請使用下面的代碼而不是$zip->addFile($file);

<?php
$zip->addFile($file_path, $filename);
?>
$files = "upload/".array('Dear GP.docx','ecommerce.doc');

應該是:

$files = array('upload/Dear GP.docx','upload/ecommerce.doc');

如果您仍然遇到問題,那么您應該檢查您是否對當前目錄具有寫權限。 你可以檢查close()的返回值來檢查文件是否真的被寫入。

$res = $zip->close();
var_dump($res);

如果寫入成功,輸出應為bool(true)

看起來您在filesize()調用中也有錯誤的 var 名稱:

header('Content-Length: ' . filesize($zipfilename));

應該是:

header('Content-Length: ' . filesize($zipname));

您還可以添加額外的驗證來檢查您添加到 zip 的文件是否實際存在,並在發送之前檢查 zip 文件是否存在。

編輯:打開顯示錯誤以幫助您在本地調試:

ini_set('display_errors', 1);
error_reporting(E_ALL);

答案很好,但請在標題前添加這些行。 Zip 文件在所有 zip 軟件(winzip、winrar 等)中打開

if (headers_sent()) 
    {
        // HTTP header has already been sent
        return false;
    }
// clean buffer(s)
while (ob_get_level() > 0)
    {
        ob_end_clean();
    }
 $zip = new ZipArchive;
        if ($zip->open('assets/myzip.zip',  ZipArchive::CREATE)) {
            $zip->addFile('folder/bootstrap.js', 'bootstrap.js');
            $zip->addFile('folder/bootstrap.min.js', 'bootstrap.min.js');
            $zip->close();
            echo 'Archive created!';
            header('Content-disposition: attachment; filename=files.zip');
            header('Content-type: application/zip');
            readfile($tmp_file);
       } else {
           echo 'Failed!';
       }

我得到了這個代碼來從一個文件夾下載文件。

我有一個客戶端“全部下載”按鈕,用於存儲在網絡服務器上的並行目錄中的文件。 與 OP 有類似的問題,在閱讀了許多類似的帖子后創建了以下代碼。

服務器在 Ubuntu 20 上運行 php7.4,不要忘記安裝你的 php 版本的 zip,我的是 php7.4-zip。 HTML 使用 Bootstrap 4.5.2 和 font-awesome 5.13.0

<?php
if( isset( $_POST["downloadAll"] ) ){

    // all folders in remote dir are given a UID as a name
    $directory = "../remoteLinuxDirectory/" . $_SESSION["folderID"];
    $fileNames = scandir( $directory );
    
    // create new archive 
    $zip = new ZipArchive;

    // create a temporary file for zip creation
    $tmp_file = tempnam( $directory, $_SESSION["folderName"] );

    if( $zip->open( $tmp_file, ZipArchive::CREATE ) ){ 

        // $i = 0,1 show the dot and double dot directory in linux
        $i=2; 

        while( $i < count( $fileNames ) ){ 

           // addFile( 'from location', 'name of individual file')
           $zip->addFile( $directory . "/" . $fileNames[ $i ], $fileNames[ $i ] ); 
           $i++;
        }

        $zip->close();
    
        // remove special characters from the about-to-be-created zip filename 
        $cleanName = str_replace(array( ".",",","/","\\"," "),'', $_SESSION["folderName"])
        header("Content-disposition: attachment; filename=" . $cleanName . ".zip");
        header('Content-type: application/zip');

        // begin the zip download
        readfile( $tmp_file );

        // removes the temporary file created in the "../remoteLinuxDirectory/"
        unlink( $tmp_file );

    }else{
        // can be removed, but will dump some info incase the $zip->open fails
        var_dump( $tmp_file );
    }
}
?>

一個 HTML 按鈕:

<form action="" method="post">
    <button class="btn btn-primary p-2 px-3">
        <input  name="downloadAll" value="1" hidden>
        <i class="fas fa-download"></i> Download All
    </button>
</form>

暫無
暫無

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

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