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

PHP 一行代碼刪除目錄下所有文件:array_map + glob 實戰

     編輯:PHP 相關知識

極簡核心代碼

<?php
// 刪除當前目錄下所有文件(不含子目錄、不含隱藏文件)
array_map('unlink', glob('*'));

// 刪除指定目錄下所有 .log 文件
array_map('unlink', glob('/var/www/logs/*.log'));

// 刪除遞歸所有子目錄文件(需 PHP 5.3+ GLOB_BRACE 或 RecursiveDirectoryIterator)
// array_map('unlink', glob('/path/**/*', GLOB_BRACE)); // 不完全支持遞歸,見下文
?>

原理解析:兩大函數的「化學反應」

執行流程:

  1. glob('*') 掃描當前目錄,返回所有非隱藏文件/目錄路徑數組
  2. array_map 遍歷數組,對每個路徑調用 unlink() 刪除文件
  3. 若遇到目錄,unlink() 返回 false 並拋出 Warning,但不中斷後續執行

glob() 模式匹配規則速查

| 模式 | 含義 | 示例匹配 | |---|---|---| | * | 任意字符(除 / 外),不匹配以 . 開頭的隱藏文件 | a.txt, sub/b.php | | ?.txt | 單字符 + .txt | 1.txt, a.txt | | [abc].php | 字符集合 | a.php, b.php | | *.{jpg,png,gif} | 大括號分組(需 GLOB_BRACE 標誌) | img.jpg, pic.png | | **/*.log | 遞歸匹配(需 GLOB_BRACE + PHP 5.3+,實測兼容性一般) | 深層目錄下的 .log |

進階版:健壯的目錄清理函數

<?php
/**
 * 安全刪除目錄下所有文件(可選遞歸、過濾模式、錯誤收集)
 *
 * @param string $dir 目標目錄(絕對路徑)
 * @param string $pattern glob 模式,默認 '*' 所有文件
 * @param bool $recursive 是否遞歸子目錄
 * @return array ['deleted' => int, 'failed' => [], 'skipped_dirs' => int]
 */
function cleanDirectory(string $dir, string $pattern = '*', bool $recursive = false): array {
    $dir = rtrim($dir, '/\\') . '/';
    if (!is_dir($dir)) throw new InvalidArgumentException("目錄不存在: $dir");

    $flags = GLOB_NOSORT; // 不排序,提升大目錄性能
    if ($recursive) {
        // 遞歸模式:使用 RecursiveDirectoryIterator(比 glob ** 更可靠)
        $files = new RegexIterator(
            new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)),
            '/^.+/'
        );
        $paths = iterator_to_array($files, false); // false: 不用路徑作鍵,避免重複覆蓋
    } else {
        // 非遞歸:glob 直接匹配
        $paths = glob($dir . $pattern, $flags);
    }

    $result = ['deleted' => 0, 'failed' => [], 'skipped_dirs' => 0];

    foreach ($paths as $path) {
        if (is_dir($path)) {
            $result['skipped_dirs']++;
            continue; // 跳過目錄,unlink 不能刪目錄
        }
        if (@unlink($path)) { // @ 抑制 Warning,自行捕獲失敗
            $result['deleted']++;
        } else {
            $result['failed'][] = $path;
        }
    }

    return $result;
}

// 使用示例
$res = cleanDirectory('/var/www/html/cache', '*.tmp', true);
echo "刪除 {$res['deleted']} 個文件,跳過 {$res['skipped_dirs']} 個目錄";
if ($res['failed']) {
    error_log("刪除失敗: " . print_r($res['failed'], true));
}
?>

常見坑點與避雷指南

| 坑點 | 現象 | 根因 | 修復 | |---|---|---|---| | **隱藏文件遺漏** | .gitignore, .env 未刪 | glob('*') 不匹配點開頭 | glob('{*,.*}', GLOB_BRACE) 或 FilesystemIterator | | **子目錄報警告** | Warning: unlink(): Is a directory | glob 返回目錄,unlink 只能刪文件 | is_file($path) && unlink($path) 判斷 | | **權限失敗靜默** | 刪除失敗無感知 | array_map 忽略返回值,unlink 只發 Warning | 捕獲返回值或 error_get_last() 記錄失敗 | | **大目錄性能** | glob 卡死、內存飆升 | 返回巨大數組佔用內存 | GLOB_NOSORT + DirectoryIterator 流式處理 | | **遞歸無限循環** | 符號鏈接導致死循環 | RecursiveDirectoryIterator 默認跟隨鏈接 | FilesystemIterator::FOLLOW_SYMLINKS 關閉 |

現代化替代:Symfony Finder / Laravel File Facade

// Laravel / Symfony Finder(表達力強、鏈式調用、自帶遞歸/過濾/大小/時間)
use Symfony\Component\Finder\Finder;

$finder = Finder::create()
    ->files()           // 只要文件
    ->name('*.log')     // 模式
    ->in('/var/log')    // 目錄
    ->date('< 30 days ago'); // 修改時間 30 天前

foreach ($finder as $file) {
    $file->delete(); // SplFileInfo::delete() 內部 unlink
}

// Laravel 簡寫
use Illuminate\Support\Facades\File;
File::cleanDirectory(storage_path('logs')); // 遞歸刪除目錄下所有文件,保留目錄結構

總結

array_map('unlink', glob('*')) 是 PHP 中「表達力最強、代碼最短」的批量刪除寫法,完美詮釋了「函數式編程思想在腳本語言中的實踐」。但生產環境請務必升級為帶錯誤收集、類型判斷、遞歸支持、權限容錯的健壯版本。記住:glob 找路徑,array_map 執行動作,is_file 保安全,錯誤收集保可觀測——這才是專業工程師的寫法。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數角色輸入/輸出
glob(pattern)文件查找器:按模式匹配路徑,返回絕對/相對路徑數組輸入:模式字符串 → 輸出:['file1.txt', 'dir/file2.jpg', ...]
array_map(callback, array)批量執行器:將回調函數應用到數組每個元素,返回結果數組輸入:'unlink' + 路徑數組 → 執行 unlink('file1.txt')... 返回 [true, true, ...]