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

PHP 文件系統操作實戰:刪除文件、遍歷目錄、篩選圖片文件

     編輯:PHP 相關知識

核心函數速覽

函數用途返回值
unlink()刪除文件bool
opendir()打開目錄句柄resource|false
readdir()讀取目錄條目string|false
closedir()關閉目錄句柄void
is_dir()判斷是否目錄bool
pathinfo()解析路徑信息array
glob()模式匹配查找文件array

場景一:安全刪除指定文件

<?php
function safeDeleteFile(string $filePath): bool {
    // 1. 路徑規範化,防止目錄遍歷攻擊
    $realPath = realpath($filePath);
    $allowedRoot = realpath(__DIR__ . '/uploads');
    
    if ($realPath === false || strpos($realPath, $allowedRoot) !== 0) {
        error_log("非法刪除嘗試: $filePath");
        return false;
    }

    // 2. 確認是文件且存在
    if (!is_file($realPath)) {
        return false;
    }

    // 3. 嘗試刪除
    if (@unlink($realPath)) {
        return true;
    }
    
    error_log("刪除失敗: $realPath");
    return false;
}

// 使用
safeDeleteFile('uploads/temp/test.txt');
?>

場景二:獲取目錄下所有文件名(遞歸/非遞歸)

非遞歸:DirectoryIterator (SPL, PHP 5+ 推薦)

<?php
function listFiles(string $dir): array {
    $files = [];
    if (!is_dir($dir)) return $files;
    
    foreach (new DirectoryIterator($dir) as $fileInfo) {
        if ($fileInfo->isDot()) continue; // 跳過 . 和 ..
        if ($fileInfo->isFile()) {
            $files[] = $fileInfo->getFilename();
        }
    }
    return $files;
}

print_r(listFiles('message/'));
?>

遞歸:RecursiveDirectoryIterator

<?php
function listFilesRecursive(string $dir): array {
    $files = [];
    $iterator = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
    );
    
    foreach ($iterator as $fileInfo) {
        if ($fileInfo->isFile()) {
            // 獲取相對路徑
            $files[] = $iterator->getSubPathname();
        }
    }
    return $files;
}
?>

場景三:篩選讀取目錄下的圖片文件

<?php
function getImageFiles(string $dir, array $extensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']): array {
    $images = [];
    if (!is_dir($dir)) return $images;
    
    // 使用 glob 模式匹配,效率高於遍歷判斷
    $patterns = array_map(fn($ext) => "$dir/*.$ext", $extensions);
    foreach ($patterns as $pattern) {
        foreach (glob($pattern) as $file) {
            if (is_file($file)) {
                $images[] = basename($file);
            }
        }
    }
    
    // 自然排序
    natsort($images);
    return array_values($images);
}

// 使用
$images = getImageFiles('images/');
print_r($images);
// 輸出: Array ( [0] => banner1.jpg [1] => banner2.png [2] => logo.gif )
?>

進階:獲取文件詳細信息陣列

<?php
function getFileDetails(string $dir): array {
    $details = [];
    foreach (new DirectoryIterator($dir) as $info) {
        if ($info->isDot() || !$info->isFile()) continue;
        
        $details[] = [
            'name'      => $info->getFilename(),
            'path'      => $info->getPathname(),
            'size'      => $info->getSize(),           // 字節
            'size_human'=> humanFileSize($info->getSize()),
            'mime'      => mime_content_type($info->getPathname()),
            'mtime'     => $info->getMTime(),          // Unix 時間戳
            'mtime_fmt' => date('Y-m-d H:i:s', $info->getMTime()),
            'extension' => strtolower($info->getExtension()),
        ];
    }
    return $details;
}

function humanFileSize(int $bytes, int $decimals = 2): string {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $factor = floor((strlen($bytes) - 1) / 3);
    return sprintf("%.{$decimals}f", $bytes / (1024 ** $factor)) . ' ' . $units[$factor];
}
?>

最佳實踐總結

  • 優先使用 SPL 迭代器 (DirectoryIterator, GlobIterator):面向對象、自動資源管理、可組合過濾器。
  • 大量文件用 glob():底層 C 實現,比 PHP 迴圈快得多。
  • 路徑安全:任何用戶輸入的路徑必須經過 realpath() 校驗是否在允許根目錄下。
  • 錯誤抑制慎用:@unlink() 僅在確認文件存在時使用,否則會掩蓋權限、鎖定等真實問題。
  • 大目錄分頁:超過萬級文件目錄,避免一次性加載到內存,使用 LimitIterator 分頁處理。

掌握這些現代 PHP 文件系統 API,能編寫出更安全、高效、可維護的文件操作代碼。

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