PHP 內建檔案系統函數功能強大,但某些系統級操作(如 tar 壓縮)仍需呼叫外部指令;而遞歸刪除非空目錄則是常見需求。本文提供兩個實用片段:system() 呼叫 tar 與自訂遞歸刪除函數 d_rmdir()。
<?php
$sourceDir = './temp'; // 要壓縮的目錄
$archive = 'tar_test.tar.gz'; // 輸出檔名
// 壓縮:-c 建立 -z gzip -v 顯示過程 -f 指定檔名
system("tar czvf " . escapeshellarg($archive) . " " . escapeshellarg($sourceDir));
// 解壓(註解啟用):
// system("tar zxvf " . escapeshellarg($archive));
?>
tar 與 gzip。tar,建議改用 ZipArchive 類別。<?php
/**
* 遞歸刪除目錄及其所有內容
* @param string $dirname 目錄路徑
* @return bool 成功返回 true
*/
function d_rmdir($dirname) {
if (!is_dir($dirname)) {
return false;
}
$handle = @opendir($dirname);
if (!$handle) return false; // 權限不足等
while (($file = @readdir($handle)) !== false) {
if ($file === '.' || $file === '..') continue;
$path = $dirname . '/' . $file;
if (is_dir($path)) {
d_rmdir($path); // 遞歸刪除子目錄
} else {
@unlink($path); // 刪除檔案
}
}
closedir($handle);
return @rmdir($dirname); // 最後刪除空目錄本身
}
// --- 使用範例 ---
if (d_rmdir('./temp')) {
echo 'success';
} else {
echo 'false';
}
?>
readdir()、unlink()、rmdir() 在權限不足時拋出警告,由回傳值判斷成敗。is_dir() 對 symlink 返回 true,遞歸會進入連結目標;若需保留連結僅刪除連結本身,請加入 is_link($path) && unlink($path) 判斷。function deleteDirRecursive($dir) {
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $file) {
$file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
}
rmdir($dir);
}
use Symfony\Component\Filesystem\Filesystem;
$fs = new Filesystem();
$fs->remove(['./temp']); // 自動處理遞歸、權限、錯誤拋出
簡單腳本可用 system('tar ...') 與自訂 d_rmdir() 快速解決問題;大型專案建議引入 ZipArchive(跨平台壓縮)與 Symfony Filesystem(健壯檔案操作),提升可維護性與安全性。