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 '未知上传错误'; } } ?>