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

PHP上传HTML表单文件至MariaDB LONGBLOB列失败求助

解决MariaDB LONGBLOB字段无法存储上传文件的问题

问题描述

尝试通过HTML表单将文件上传至MariaDB的buchzusammenfassung表,目前表中已成功生成包含idSchueler和idBuch的条目,但文件始终无法存入LONGBLOB类型的datei字段中。

现有代码

显示上传表单的PHP代码

<?php
session_start();
if ($_SESSION["rolle"] === "schueler" && isset($_GET['id'])) {
    $buchId = $_GET['id'];

    $dbHost = '...';
    $dbUser = '...';
    $dbPass = '...';
    $dbName = '...';

    $conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);

    if ($conn->connect_error) {
        die("Verbindung zur Datenbank fehlgeschlagen: " . $conn->connect_error);
    }

    // 获取书籍信息
    $sql = "SELECT title FROM buecher WHERE id = ?";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("i", $buchId);
    $stmt->execute();
    $result = $stmt->get_result();

    if ($result->num_rows == 1) {
        $row = $result->fetch_assoc();
        $buchtitel = $row['title'];

        // 输出上传表单
        echo '<h2>Zusammenfassung für das Buch: ' . $buchtitel . '</h2>';
        echo '<form action="upload_zusammenfassung.php" method="post" enctype="multipart/form-data">';
        echo '    <input type="file" name="zusammenfassung" id="zusammenfassung">';
        echo '    <input type="hidden" name="buch_id" value="' . $buchId . '">';
        echo '    <input type="submit" value="Zusammenfassung hochladen">';
        echo '</form>';
    } else {
        echo "Buch nicht gefunden.";
    }

    $stmt->close();
}
?>

处理上传的PHP代码

<?php
error_reporting(E_ALL);

session_start();

if ($_SESSION["rolle"] === "schueler" && isset($_FILES['zusammenfassung']) && isset($_POST['buch_id'])) {
    // 连接数据库
    $dbHost = '...';
    $dbUser = '...';
    $dbPass = '...';
    $dbName = '...';

    $conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);

    if ($conn->connect_error) {
        die("Verbindung zur Datenbank fehlgeschlagen: " . $conn->connect_error);
    }

    $buchId = $_POST['buch_id'];

    // 获取文件信息
    $dateiTmpName = $_FILES['zusammenfassung']['tmp_name'];
    $dateiDaten = file_get_contents($dateiTmpName);

    // 根据用户名获取学生ID
    $schuelerBenutzername = $_SESSION["username"];

    $sqlSchuelerId = "SELECT id_student FROM students WHERE newUsername = ?";
    $stmtSchuelerId = $conn->prepare($sqlSchuelerId);
    $stmtSchuelerId->bind_param("s", $schuelerBenutzername);
    $stmtSchuelerId->execute();
    $stmtSchuelerId->bind_result($schuelerId);
    $stmtSchuelerId->fetch();
    $stmtSchuelerId->close();

    // 插入文件到数据库
    $sql = "INSERT INTO buchzusammenfassung (idSchueler, idBuch, datei) VALUES (?, ?, ?)";
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("iib", $schuelerId, $buchId, $dateiDaten);

    if ($stmt->execute()) {
        echo "Die Zusammenfassung wurde erfolgreich hochgeladen und in der Datenbank gespeichert.";
    } else {
        echo "Fehler beim Hochladen der Zusammenfassung.";
    }

    $stmt->close();
    $conn->close();
}
?>

问题分析与解决方案

1. 缺失文件上传错误检查

现有代码未验证文件是否成功上传,若上传过程中出现错误(如临时文件丢失、大小超限),会导致file_get_contents读取失败,最终存入空值。

修复: 在处理上传的代码开头加入错误检查:

if ($_FILES['zusammenfassung']['error'] !== UPLOAD_ERR_OK) {
    die("文件上传失败,错误码:" . $_FILES['zusammenfassung']['error']);
}

// 检查临时文件是否存在
if (!file_exists($dateiTmpName)) {
    die("临时文件不存在");
}

// 验证文件读取是否成功
$dateiDaten = file_get_contents($dateiTmpName);
if ($dateiDaten === false) {
    die("无法读取上传文件");
}

2. Blob数据绑定方式错误

使用bind_param("iib", ...)直接绑定大文件数据时,若文件大小超过MySQL的数据包限制,会导致数据截断或无法写入。正确做法是配合send_long_data方法分块传递Blob数据。

修复: 修改插入数据的代码段:

// 预处理SQL语句
$sql = "INSERT INTO buchzusammenfassung (idSchueler, idBuch, datei) VALUES (?, ?, ?)";
$stmt = $conn->prepare($sql);
if (!$stmt) {
    die("预处理语句创建失败:" . $conn->error);
}

// 绑定前两个参数,第三个Blob参数先设为null
$stmt->bind_param("iiB", $schuelerId, $buchId, null);
// 分块发送Blob数据
$stmt->send_long_data(2, $dateiDaten);

// 执行插入
if ($stmt->execute()) {
    echo "摘要已成功上传并存储到数据库。";
} else {
    echo "上传失败:" . $stmt->error;
}

3. 数据库与PHP配置限制

  • MariaDB配置: 检查max_allowed_packet参数,若值过小会限制Blob数据的大小。执行以下SQL查询当前值:

    SHOW VARIABLES LIKE 'max_allowed_packet';
    

    若值小于文件大小,需修改my.cnf(或my.ini):

    [mysqld]
    max_allowed_packet=64M
    

    重启MariaDB服务生效。

  • PHP配置: 检查php.ini中以下参数,确保上传文件大小不被限制:

    • upload_max_filesize:单个上传文件的最大大小
    • post_max_size:POST请求的总大小(需大于upload_max_filesize)
    • memory_limit:PHP可用内存上限(需足够读取文件)

4. 补充学生ID查询的错误检查

现有代码未验证学生ID是否查询成功,若用户名不存在会导致idSchueler为空,影响插入逻辑。

修复:

$stmtSchuelerId->execute();
$stmtSchuelerId->bind_result($schuelerId);
if (!$stmtSchuelerId->fetch()) {
    die("未找到对应用户的学生ID");
}
$stmtSchuelerId->close();

完整修复后的处理代码

<?php
error_reporting(E_ALL);
ini_set('display_errors', 1); // 开启错误显示,方便调试

session_start();

if ($_SESSION["rolle"] === "schueler" && isset($_FILES['zusammenfassung']) && isset($_POST['buch_id'])) {
    // 检查文件上传状态
    if ($_FILES['zusammenfassung']['error'] !== UPLOAD_ERR_OK) {
        die("文件上传失败,错误码:" . $_FILES['zusammenfassung']['error']);
    }

    $dateiTmpName = $_FILES['zusammenfassung']['tmp_name'];
    // 验证临时文件存在性
    if (!file_exists($dateiTmpName)) {
        die("临时文件丢失");
    }

    // 读取文件内容
    $dateiDaten = file_get_contents($dateiTmpName);
    if ($dateiDaten === false) {
        die("无法读取上传文件");
    }

    // 数据库连接
    $dbHost = '...';
    $dbUser = '...';
    $dbPass = '...';
    $dbName = '...';

    $conn = new mysqli($dbHost, $dbUser, $dbPass, $dbName);
    if ($conn->connect_error) {
        die("数据库连接失败:" . $conn->connect_error);
    }

    $buchId = $_POST['buch_id'];
    $schuelerBenutzername = $_SESSION["username"];

    // 查询学生ID
    $sqlSchuelerId = "SELECT id_student FROM students WHERE newUsername = ?";
    $stmtSchuelerId = $conn->prepare($sqlSchuelerId);
    $stmtSchuelerId->bind_param("s", $schuelerBenutzername);
    $stmtSchuelerId->execute();
    $stmtSchuelerId->bind_result($schuelerId);
    if (!$stmtSchuelerId->fetch()) {
        die("未找到该用户的学生信息");
    }
    $stmtSchuelerId->close();

    // 插入Blob数据到数据库
    $sql = "INSERT INTO buchzusammenfassung (idSchueler, idBuch, datei) VALUES (?, ?, ?)";
    $stmt = $conn->prepare($sql);
    if (!$stmt) {
        die("预处理语句创建失败:" . $conn->error);
    }

    $stmt->bind_param("iiB", $schuelerId, $buchId, null);
    $stmt->send_long_data(2, $dateiDaten);

    if ($stmt->execute()) {
        echo "摘要已成功上传并存储到数据库。";
    } else {
        echo "上传失败:" . $stmt->error;
    }

    $stmt->close();
    $conn->close();
} else {
    die("权限不足或参数缺失");
}
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 21:32:02