You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将PDF文件存入MySQL数据库?(PHP实现)

问题分析与修复方案

你的代码存在多个关键问题,导致PDF上传异常,同时还存在安全隐患,以下是具体修复内容:

核心问题点

  • 执行顺序错误:先插入数据库再检查文件上传状态,导致上传失败时数据库已存入无效文件名
  • 错误检查滞后:文件上传错误检查放在移动文件之后,无法提前终止错误流程
  • 无文件类型校验:未限制仅允许PDF文件上传,存在安全风险
  • SQL注入漏洞:直接拼接用户输入到SQL语句,极易被恶意攻击
  • 文件名处理不安全:直接使用原始文件名,存在重名、路径遍历风险

修复后的代码

public function insertUM() {
    // 先校验必要参数和文件是否存在
    if (!empty($_POST['um-area']) && isset($_FILES['pdf'])) {
        // 1. 先检查文件上传基础错误
        if ($_FILES['pdf']['error'] !== UPLOAD_ERR_OK) {
            echo "文件上传失败,错误码: " . $_FILES['pdf']['error'];
            return;
        }

        // 2. 验证文件为PDF格式(校验真实MIME类型)
        $allowedMimes = ['application/pdf'];
        $fileMime = mime_content_type($_FILES['pdf']['tmp_name']);
        if (!in_array($fileMime, $allowedMimes)) {
            echo "仅支持上传PDF格式文件";
            return;
        }

        // 3. 安全处理文件名,避免重名和路径遍历
        $fileInfo = pathinfo($_FILES['pdf']['name']);
        $safeFilename = uniqid($fileInfo['filename'] . '_', true) . '.' . $fileInfo['extension'];
        $uploadDir = 'pdf/';
        
        // 确保上传目录存在,不存在则创建
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        $targetPath = $uploadDir . $safeFilename;

        // 4. 使用预处理SQL语句,彻底避免注入
        $insertSql = "INSERT INTO " . $this->usermanualFiles . " (area, subject, description, filename) VALUES(?, ?, ?, ?)";
        $stmt = mysqli_prepare($this->dbConnect, $insertSql);
        if (!$stmt) {
            echo "数据库语句准备失败: " . mysqli_error($this->dbConnect);
            return;
        }
        mysqli_stmt_bind_param($stmt, 'ssss', $_POST['um-area'], $_POST['um-subject'], $_POST['um-description'], $safeFilename);
        
        // 5. 先完成文件上传,成功后再插入数据库
        if (move_uploaded_file($_FILES['pdf']['tmp_name'], $targetPath)) {
            if (mysqli_stmt_execute($stmt)) {
                echo "文件 " . $safeFilename . " 上传成功,数据已同步存入数据库。";
            } else {
                // 数据库插入失败,回滚已上传的文件
                unlink($targetPath);
                echo "数据存入失败: " . mysqli_stmt_error($stmt);
            }
        } else {
            echo "文件上传失败,请检查目录写入权限。";
        }
        mysqli_stmt_close($stmt);
    } else {
        echo "缺少必要的表单参数或上传文件";
    }
}

关键修复说明

  1. 调整流程顺序:先完成文件校验、错误检查,再执行文件上传和数据库插入,保证数据一致性
  2. 真实类型校验:通过mime_content_type校验文件真实类型,避免仅靠后缀名判断的漏洞
  3. 安全文件名生成:用uniqid生成唯一文件名,解决重名和路径遍历问题
  4. 预处理SQL:彻底消除SQL注入风险,提升代码安全性
  5. 错误回滚机制:数据库插入失败时自动删除已上传文件,避免残留垃圾文件
  6. 目录自动创建:自动生成上传目录,避免因目录不存在导致的上传失败

内容的提问来源于stack exchange,提问作者sssxxxyyy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 11:02:33