diff --git a/files.php b/files.php new file mode 100644 index 0000000..bf6b624 --- /dev/null +++ b/files.php @@ -0,0 +1,188 @@ + 50 * 1024 * 1024, // 50MB + 'allowed_types' => [ + 'image/jpeg', + 'image/png', + 'application/pdf', + 'text/plain' + ], + 'upload_dir' => __DIR__ . '/uploads/', + 'csrf_token' => 'secure_token_here' // 生产环境应使用更安全的生成方式 +]; + +// 处理文件上传 +$error = ''; +$success = ''; + +if ($_SERVER['REQUEST_METHOD'] === 'POST') { + // CSRF 验证 + if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $config['csrf_token']) { + $error = '无效的请求令牌'; + } else { + try { + // 验证上传文件 + $uploadedFile = $_FILES['file'] ?? null; + + if (!$uploadedFile || $uploadedFile['error'] !== UPLOAD_ERR_OK) { + throw new RuntimeException(handleUploadError($uploadedFile['error'])); + } + + // 验证文件大小 + if ($uploadedFile['size'] > $config['max_file_size']) { + throw new RuntimeException('文件大小超过50MB限制'); + } + + // 验证文件类型 + $finfo = new finfo(FILEINFO_MIME_TYPE); + $mimeType = $finfo->file($uploadedFile['tmp_name']); + + if (!in_array($mimeType, $config['allowed_types'])) { + throw new RuntimeException('不支持的文件类型'); + } + + // 创建上传目录 + if (!is_dir($config['upload_dir']) && !mkdir($config['upload_dir'], 0755, true)) { + throw new RuntimeException('无法创建上传目录'); + } + + // 生成安全文件名 + $extension = pathinfo($uploadedFile['name'], PATHINFO_EXTENSION); + $safeName = sprintf('%s.%s', bin2hex(random_bytes(8)), $extension); + $targetPath = $config['upload_dir'] . $safeName; + + // 移动文件 + if (!move_uploaded_file($uploadedFile['tmp_name'], $targetPath)) { + throw new RuntimeException('文件保存失败'); + } + + $success = sprintf('文件上传成功!文件名:%s', htmlspecialchars($safeName)); + } catch (RuntimeException $e) { + $error = $e->getMessage(); + } + } +} + +function handleUploadError($code) { + switch ($code) { + case UPLOAD_ERR_INI_SIZE: + case UPLOAD_ERR_FORM_SIZE: + return '文件大小超过服务器限制'; + case UPLOAD_ERR_PARTIAL: + return '文件只有部分被上传'; + case UPLOAD_ERR_NO_FILE: + return '没有文件被上传'; + case UPLOAD_ERR_NO_TMP_DIR: + return '缺少临时文件夹'; + case UPLOAD_ERR_CANT_WRITE: + return '写入磁盘失败'; + default: + return '未知上传错误'; + } +} +?> + + + +
+ + +