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]";
}
}
}
?pwd=密碼 可預填 MD5)implode('', file($path)) 會將整檔讀入記憶體,大檔案建議改用串流讀取max_execution_time,需 set_time_limit(0)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 實現。