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

使用 PHP 建構 Web 檔案管理系統:目錄列表、檔案操作與自動備份

     編輯:PHP 相關知識

PHP 提供豐富的檔案系統函式,讓開發者能輕鬆建立 Web 架構的檔案管理器。本文將示範如何實作目錄瀏覽、檔案上傳下載、複製移動刪除等核心功能,並結合排程實現自動化備份。

跨平台路徑處理

Windows 支援正斜線(/)與反斜線(\),Linux/Unix 僅支援正斜線。為確保跨平台相容,統一使用正斜線:

<?php
$dirPath = '/home/user/documents'; // 統一使用正斜線
?>

目錄列表功能

<?php
function listDirectory(string $path): string {
    if (!is_dir($path) || !is_readable($path)) {
        throw new Exception("目錄不存在或不可讀取:$path");
    }

    $handle = opendir($path);
    $files = [];

    while (($entry = readdir($handle)) !== false) {
        if ($entry !== '.' && $entry !== '..') {
            $fullPath = $path . '/' . $entry;
            $files[] = [
                'name' => $entry,
                'path' => $fullPath,
                'is_dir' => is_dir($fullPath),
                'size' => is_file($fullPath) ? filesize($fullPath) : null,
                'mtime' => filemtime($fullPath),
                'perms' => substr(sprintf('%o', fileperms($fullPath)), -4)
            ];
        }
    }
    closedir($handle);

    // 排序:資料夾優先,再按名稱
    usort($files, fn($a, $b) => 
        ($a['is_dir'] === $b['is_dir']) 
            ? strnatcasecmp($a['name'], $b['name']) 
            : ($a['is_dir'] ? -1 : 1)
    );

    return json_encode($files, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}

// 使用範例
header('Content-Type: application/json; charset=utf-8');
echo listDirectory($_GET['path'] ?? '/var/www/html');
?>

檔案上傳處理

<?php
function handleUpload(array $file, string $targetDir, array $allowedTypes = [], int $maxSize = 10485760): array {
    // 驗證上傳錯誤
    if ($file['error'] !== UPLOAD_ERR_OK) {
        throw new Exception('上傳錯誤代碼:' . $file['error']);
    }

    // 驗證檔案大小
    if ($file['size'] > $maxSize) {
        throw new Exception('檔案大小超過限制(' . formatBytes($maxSize) . ')');
    }

    // 驗證 MIME 類型
    $finfo = new finfo(FILEINFO_MIME_TYPE);
    $mimeType = $finfo->file($file['tmp_name']);
    if (!empty($allowedTypes) && !in_array($mimeType, $allowedTypes, true)) {
        throw new Exception('不允許的檔案類型:' . $mimeType);
    }

    // 確保目標目錄存在
    if (!is_dir($targetDir)) {
        mkdir($targetDir, 0755, true);
    }

    // 產生安全檔名
    $extension = pathinfo($file['name'], PATHINFO_EXTENSION);
    $safeName = bin2hex(random_bytes(16)) . ($extension ? '.' . $extension : '');
    $targetPath = $targetDir . '/' . $safeName;

    // 移動檔案
    if (!move_uploaded_file($file['tmp_name'], $targetPath)) {
        throw new Exception('檔案移動失敗');
    }

    // 設定權限
    chmod($targetPath, 0644);

    return [
        'original_name' => $file['name'],
        'saved_name' => $safeName,
        'path' => $targetPath,
        'size' => $file['size'],
        'mime' => $mimeType
    ];
}

function formatBytes(int $bytes, int $precision = 2): string {
    $units = ['B', 'KB', 'MB', 'GB', 'TB'];
    $bytes = max($bytes, 0);
    $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
    $pow = min($pow, count($units) - 1);
    $bytes /= (1 << (10 * $pow));
    return round($bytes, $precision) . ' ' . $units[$pow];
}
?>

檔案複製與備份腳本

<?php
// backup.php - 可由 cron 排程執行
$source = '/var/www/html/config/database.php';
$backupDir = '/backups/db_config/' . date('Y-m');

if (!is_dir($backupDir)) {
    mkdir($backupDir, 0755, true);
}

$target = $backupDir . '/database_' . date('Ymd_His') . '.php';

if (copy($source, $target)) {
    chmod($target, 0644);
    echo "備份成功:$target\n";
    
    // 清理 30 天前的備份
    $files = glob($backupDir . '/database_*.php');
    $cutoff = time() - (30 * 86400);
    foreach ($files as $file) {
        if (filemtime($file) < $cutoff) {
            unlink($file);
        }
    }
} else {
    error_log("備份失敗:$source -> $target");
    exit(1);
}
?>

Cron 排程設定

# 每天凌晨 2:30 執行備份
30 2 * * * www-data /usr/bin/php /var/www/scripts/backup.php >> /var/log/backup.log 2>&1

# 每小時同步上傳目錄到備份伺服器
0 * * * * www-data rsync -az /var/www/uploads/ backup-server:/backups/uploads/

檔案刪除與安全性考量

<?php
function secureDelete(string $path, string $baseDir): bool {
    // 解析真實路徑,防止目錄遍歷攻擊
    $realPath = realpath($path);
    $realBase = realpath($baseDir);

    if ($realPath === false || $realBase === false) {
        return false;
    }

    // 確保目標在基底目錄內
    if (strpos($realPath, $realBase) !== 0) {
        return false; // 嘗試存取基底目錄外的檔案
    }

    // 記錄刪除操作
    error_log("DELETE: $realPath by " . ($_SERVER['REMOTE_ADDR'] ?? 'cli'));

    if (is_dir($realPath)) {
        return rmdir($realPath); // 僅刪除空目錄,避免誤刪
    }

    return unlink($realPath);
}
?>

前端整合建議

  • 使用 JavaScript Fetch API 進行非同步操作
  • 實作拖曳上傳與進度顯示
  • 提供檔案預覽(圖片、PDF、文字檔)
  • 加入右鍵選單:重新命名、複製、移動、下載、刪除
  • 實作多檔案選取與批次操作

建構完整的檔案管理系統還需考慮使用者權限控制、操作日誌審計、儲存空間配額、檔案版本控制等進階功能。建議參考成熟開源專案如 FileGator、Tiny File Manager 或對接雲端儲存服務(S3、Google Drive API)以擴充能力。

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