Thinkphp6 利用 ZipArchive 打包下載檔案

TechKoga發表於2020-08-18

(一) 下載tp6框架

composer create-project topthink/think tp6

(二)打包下載類

<?php
    namespace Jrk;

    class Zipdown
    {
       /**
        * 打包壓縮檔案及資料夾
        *
        * @Author Hhy <jackhhy520@qq.com>
        * @DateTime 2020-07-10 13:20:06
        * @param array $files
        * @param string $zipName 壓縮包名稱
        * @param boolean $wen 
        * @param boolean $isDown
        * @return void
        */ 
       public function zip_file($files = [], $zipName = '', $wen = true,$isDown = true){

        $zip_file_path='zip/';
        // 檔名為空則生成檔名
        if (empty($zipName)) {
            $zipName = $zip_file_path.date('YmdHis') . '.zip';
        }else{
            $zipName=$zip_file_path.$zipName.'.zip';
        }

        // 例項化類,使用本類,linux需開啟zlib,windows需取消php_zip.dll前的註釋
        $zip = new \ZipArchive;
        /*
        * 透過ZipArchive的物件處理zip檔案
        * $zip->open這個方法如果對zip檔案物件操作成功,$zip->open這個方法會返回TRUE
        * $zip->open這個方法第一個參數列示處理的zip檔名。
        * 這裡重點說下第二個引數,它表示處理模式
        * ZipArchive::OVERWRITE 總是以一個新的壓縮包開始,此模式下如果已經存在則會被覆蓋。
        * ZipArchive::OVERWRITE 不會新建,只有當前存在這個壓縮包的時候,它才有效
        * */
        if ($zip->open($zipName, \ZIPARCHIVE::OVERWRITE | \ZIPARCHIVE::CREATE) !== true) {
            exit('無法開啟檔案,或者檔案建立失敗');
        }

              // 資料夾打包處理
           if (is_string($files)) {
                // 資料夾整體打包
                $this->addFileToZip($files, $zip);
            } else {
                 // 檔案打包
                foreach ($files as $val) {
                    if(file_exists(app()->getRootPath().'public'.$val['att_dir'])){
                        if($wen){
                            //根據儲存的資料夾打包分層
                            $zip->addFile(app()->getRootPath().'public'.$val['att_dir'], iconv('UTF-8','gbk',$val['img_dir'].'/'.$val['name']));
                        }else{
                            //不分層
                            $zip->addFile(app()->getRootPath().'public'.$val['att_dir'], iconv('UTF-8','gbk',$val['name']));
                        }
                    }
                }
            }
            // 關閉
            $zip->close();

            // 驗證檔案是否存在
            if (!file_exists($zipName)) {
                exit("檔案不存在");
            }

        if ($isDown) {
            // ob_clean();
             // 下載壓縮包
             header("Cache-Control: public");
             header("Content-Description: File Transfer");
             header('Content-disposition: attachment; filename=' . basename($zipName)); //檔名
             header("Content-Type: application/zip"); //zip格式的
             header("Content-Transfer-Encoding: binary"); //告訴瀏覽器,這是二進位制檔案
             header('Content-Length: ' . filesize($zipName)); //告訴瀏覽器,檔案大小
             @readfile($zipName);//ob_end_clean();
             @unlink(app()->getRootPath().'public/'.$zipName);//刪除壓縮包

         } else {
             // 直接返回壓縮包地址
             return $zipName;
         }
       }

     /**
      * 新增檔案至壓縮包
      * @Author Hhy <jackhhy520@qq.com>
      * @DateTime 2020-07-10 13:20:26
      * @param [type] $path
      * @param [type] $zip
      * @return void
      */  
     public function addFileToZip($path, $zip)
       {
           // 開啟資料夾
           $handler = opendir($path);
           while (($filename = readdir($handler)) !== false) {
               if ($filename != "." && $filename != "..") {
                   // 編碼轉換
                   $filename = iconv('gb2312', 'utf-8', $filename);
                   // 資料夾檔名字為'.'和‘..’,不要對他們進行操作
                   if (is_dir($path . "/" . $filename)) {
                       // 如果讀取的某個物件是資料夾,則遞迴
                       $this->addFileToZip($path . "/" . $filename, $zip);
                   } else {
                       // 將檔案加入zip物件
                       $file_path = $path . "/" . $filename;
                       $zip->addFile($file_path, basename($file_path));
                   }
               }
           }
           // 關閉資料夾
           @closedir($path);
       }

       /**
        * 壓縮檔案解壓
        *
        * @Author Hhy <jackhhy520@qq.com>
        * @DateTime 2020-07-10 13:23:11
        * @param [type] $file
        * @param [type] $dirname
        * @return void
        */
    public  function unzip_file($file, $dirname)
       {
           if (!file_exists($file)) {
               return false;
           }
           // zip例項化物件
           $zipArc = new \ZipArchive();
           // 開啟檔案
           if (!$zipArc->open($file)) {
               return false;
           }
           // 解壓檔案
           if (!$zipArc->extractTo($dirname)) {
               // 關閉
               $zipArc->close();
               return false;
           }
           return $zipArc->close();
       }
    }

(三)使用,親測有效

 /**
     * @author: Hhy <jackhhy520@qq.com>
     * @date: 2020/7/2 0002
     * @describe:打包下載
     */
    public function download(){
      $id= $this->request->param("id");
        if (is_array($id)){
            $ids=$id;
        }else{
            $ids=@explode(",",$id);
        }
        $data=$this->model->where('id', 'in',$ids)->select()->toArray();
        //dd($data);

        if (empty($data)) {
            $this->error("暫無資料");
        }
        $zip=new Jrk\Zipdown();
        //打包下載
         $zip->zip_file($data);
    }
本作品採用《CC 協議》,轉載必須註明作者和本文連結
愛程式碼,不愛程式設計的小夥子 ^v^

相關文章