專案需定期清理上傳目錄,僅保留特定尺寸的頭像圖片(如 180x180.jpg、30x30.jpg 等),刪除其他雜項檔案。本文提供一個遞迴掃描並依條件刪除的完整函數。
<?php
/**
* 遞迴刪除指定目錄下的非法檔案
* @param string $dir 目標目錄路徑
*/
function my_del($dir) {
if (is_dir($dir)) {
// 開啟目錄遞迴處理子項目
if ($handle = opendir($dir)) {
while (false !== ($file = readdir($handle))) {
if ($file !== '.' && $file !== '..') {
my_del($dir . '/' . $file); // 遞迴處理
}
}
closedir($handle);
}
} else {
// 檔案層級:保留白名單圖片,其餘刪除
$allowed = ['180x180.jpg', '30x30.jpg', '45x45.jpg', '90x90.jpg'];
$filename = basename($dir);
// 1. 檢查副檔名是否為 .jpg
if (strripos($filename, '.jpg') === false || substr($filename, -4) !== '.jpg') {
@unlink($dir);
return;
}
// 2. 檢查檔名是否在白名單
if (!in_array($filename, $allowed)) {
@unlink($dir);
return;
}
// 3. 進一步驗證圖片實際內容(防止偽裝副檔名)
$info = @getimagesize($dir);
if (!$info || $info[2] !== IMAGETYPE_JPEG) {
@unlink($dir);
}
}
}
// 使用範例
$targetDir = 'D:/xampp/htdocs/www/avatar001/12/47/';
my_del($targetDir);
?>
opendir → readdir → 遞迴呼叫 → closedir 標準模式。getimagesize() 檢查 MIME 類型為 JPEG (常數 IMAGETYPE_JPEG = 2),防止惡意上傳偽裝副檔名的腳本。@:避免權限不足或檔案不存在時噴出警告,視專案需求決定是否保留。@ 並記錄錯誤日誌,便於追蹤刪除失敗原因。可依需求調整保留條件:
filemtime()。getimagesize() 回傳的寬高。rename() 移至隔離區,保留審計軌跡。