首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 線上打包網站並壓縮為 ZIP:密碼保護、目錄排除、進度顯示完整實作

     編輯:PHP 綜合知識

功能特色

  • 密碼保護介面 (MD5 驗證)
  • 勾選要壓縮的檔案/目錄 (含子目錄遞歸)
  • 指定排除目錄 (相對路徑,逗號分隔)
  • 自訂輸出目錄與檔名
  • 保留原始目錄結構
  • 顯示壓縮進度與結果下載連結

核心類別:PHPzip 純 PHP 實現 ZIP 封裝

class PHPzip {
    var $file_count = 0;
    var $datastr_len = 0;
    var $dirstr_len = 0;
    var $filedata = '';
    var $gzfilename;
    var $fp;
    var $dirstr = '';

    // Unix 時間轉 DOS 格式
    function unix2DosTime($unixtime = 0) {
        $timearray = ($unixtime == 0) ? getdate() : getdate($unixtime);
        if ($timearray['year'] < 1980) {
            $timearray['year'] = 1980; $timearray['mon'] = 1; $timearray['mday'] = 1;
            $timearray['hours'] = 0; $timearray['minutes'] = 0; $timearray['seconds'] = 0;
        }
        return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) |
               ($timearray['mday'] << 16) | ($timearray['hours'] << 11) |
               ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
    }

    // 初始化 ZIP 檔案
    function startfile($path = 'myzip.zip') {
        $this->gzfilename = $path;
        // 建立目錄結構
        $mypathdir = [];
        do { $mypathdir[] = $path = dirname($path); } while ($path != '.');
        @end($mypathdir);
        do { @mkdir($path); } while (@prev($mypathdir));
        if ($this->fp = @fopen($this->gzfilename, "w")) return true;
        return false;
    }

    // 加入檔案
    function addfile($data, $name) {
        $name = str_replace('\\', '/', $name);
        if (substr($name, -1) == '/') return $this->adddir($name);
        // 構建 Local File Header + File Data + Data Descriptor
        // ... (完整代碼見原文,涉及二進位封裝細節)
    }

    // 加入目錄
    function adddir($name) { /* ... */ }

    // 完成封裝:寫入 Central Directory + End of Central Directory
    function createfile() { /* ... */ }
}

遞歸掃描與壓縮流程

function listfiles($dir = ".") {
    global $faisunZIP;
    $sub_file_num = 0;
    if (is_file($dir)) {
        if (realpath($faisunZIP->gzfilename) != realpath($dir)) {
            $faisunZIP->addfile(implode('', file($dir)), $dir);
            return 1;
        }
        return 0;
    }
    $handle = opendir($dir);
    // 排除目錄處理
    $to_exclude = !empty($_POST['toexlude']) ? $_POST['toexlude'] : '';
    $exclude = empty($to_exclude) ? [] : explode(',', $to_exclude);
    while ($file = readdir($handle)) {
        if ($file == "." || $file == ".." || $file == 'wp-content') continue;
        $full = "$dir/$file";
        if (is_dir($full) && !in_array($full, $exclude)) {
            $sub_file_num += listfiles($full);
        } else {
            if (realpath($faisunZIP->gzfilename) != realpath($full)) {
                $faisunZIP->addfile(implode('', file($full)), $full);
                $sub_file_num++;
            }
        }
    }
    closedir($handle);
    if (!$sub_file_num) $faisunZIP->addfile("", "$dir/");
    return $sub_file_num;
}

檔案大小格式化

function num_bitunit($num) {
    $units = [' B', ' KB', ' MB', ' GB'];
    for ($k = 0; $k < count($units); $k++) {
        if ($num >= pow(2, 10*$k) - 1) {
            return (ceil($num / pow(2, 10*$k) * 100) / 100) . " $units[$k]";
        }
    }
}

介面流程

  1. 輸入密碼驗證 (URL 參數 ?pwd=密碼 可預填 MD5)
  2. 2. 勾選要壓縮的檔案/目錄 (預設全選,排除自身腳本) 3. 設定排除目錄、輸出目錄、ZIP 檔名 4. 點擊「開始壓縮」,顯示進度 5. 完成提供下載連結與檔案大小

安全與效能注意事項

  • 密碼傳輸:生產環境必須使用 HTTPS
  • 記憶體限制:implode('', file($path)) 會將整檔讀入記憶體,大檔案建議改用串流讀取
  • 執行時間:大型網站壓縮可能超過 max_execution_time,需 set_time_limit(0)
  • 權限控制:輸出目錄需可寫,避免洩露敏感檔案
  • 現代替代:PHP 5.2+ 可用 ZipArchive 內建類別,效能更好、支援加密

ZipArchive 現代寫法對比

$zip = new ZipArchive();
$zip->open('backup.zip', ZipArchive::CREATE);
$files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('.'));
foreach ($files as $file) {
    if ($file->isFile() && $file->getFilename() != 'backup.zip') {
        $zip->addFile($file->getRealPath(), $file->getPathname());
    }
}
$zip->close();

建議新專案直接使用 ZipArchive,僅在極舊環境 (PHP < 5.2) 才需純 PHP 實現。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved