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