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

PHP+MySQL多文件上传序列化数据被截断问题求助

问题描述

开发基于PHP和MySQL的多文件批量上传应用,将文件路径序列化后存入MySQL数据库。上传1-4个文件时一切正常,但上传超过4个文件时,MySQL会截断序列化后的末尾数据,导致数据失效,无法正常反序列化查看文件。

正常序列化数据(2个文件):

a:2:{i:0;s:22:"uploads/HqihCeKwvR.png";i:1;s:22:"uploads/cQqshZLoNB.png";}

截断后的序列化数据(8个文件):

a:8:{i:0;s:22:"uploads/nQEOmDelCR.png";i:1;s:22:"uploads/qMCJaNsSPl.png";i:2;s:22:"uploads/W0oUaN3GZm.png";i:3;s:22:"uploads/qJEYRkh04I.png";i:4;s:22:"uploads/h1SozRvFZV.png";i:5;s:22:"uploads/bPcJ32yWuC.png";i:6;s:22:"uploads/OURS3jCzIp.jpg";i:7;s:22:"up

相关代码

Upload.php

$qualification = multiple_upload($_FILES["qualification"]);

function multiple_upload($file)
{
    $target_dir = "uploads/";
    $uploadOk = 1;

    $countfiles  = count($_FILES['qualification']['name']);

    for ($i = 0; $i < $countfiles; $i++) {
        $file_name = generateRandomString();
        $target_file = $target_dir . basename($_FILES['qualification']['name'][$i]);

        $imageFileType = strtolower(pathinfo($target_file, PATHINFO_EXTENSION));
        $file_path = $target_dir . "" . $file_name . "." . $imageFileType;

        $qualifications[] = $file_path;
        // Allow certain file formats
        if (
            $imageFileType != "jpg" || $imageFileType != "png" || $imageFileType != "jpeg" || $imageFileType != "pdf" || $imageFileType != "doc" || $imageFileType != "docx"
            || $imageFileType != "gif"
        ) {
            $imageFileType = $imageFileType;
        } else {
            die("Sorry, only JPG, JPEG, PNG & GIF files are allowed.");
            $uploadOk = 0;
        }

        if (move_uploaded_file($_FILES['qualification']['tmp_name'][$i], $file_path)) {
            echo $file_path;
        } else {
            // die("Sorry, there was an error uploading your file.");
        }
    }
    return serialize($qualifications);
}

function generateRandomString($length = 10)
{
    return substr(str_shuffle(str_repeat($x = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', ceil($length / strlen($x)))), 1, $length);
}

$sql = "
      INSERT INTO 
          staff_info 
        SET 
          qualification = '$qualification '";

if ($conn->query($sql) === TRUE) {
    echo "successful...";
    // header("location: upload_successful.html");
} else {
    echo "Error: " . $sql . "<br>" . $conn->error;
}

View.php

<?php
    $qualifications = unserialize($row["qualification"]);
    foreach ($qualifications as $key => $value) {
        echo '<img src="' . $value . '" style="width: 300px; height: 300px; object-fit:cover" alt=""> <br />';
    }
?>
解决方案

核心原因

MySQL表中qualification字段的长度不足,当前大概率为VARCHAR(255)这类短长度类型。当序列化后的字符串超过字段定义长度时,MySQL会自动截断数据,破坏序列化结构,导致无法反序列化。

1. 修改MySQL字段类型/长度

执行SQL语句将字段改为TEXT或LONGTEXT,确保能容纳足够长的序列化字符串:

-- 改用TEXT类型,最大支持65535字符
ALTER TABLE staff_info MODIFY COLUMN qualification TEXT;

-- 若需要存储更长内容,使用LONGTEXT(最大支持4GB)
-- ALTER TABLE staff_info MODIFY COLUMN qualification LONGTEXT;

2. 修复SQL注入风险与数据存储异常

原代码直接拼接SQL语句存在严重安全隐患,同时特殊字符可能导致存储异常,改用预处理语句:

// 替换原有INSERT代码
$sql = "INSERT INTO staff_info SET qualification = ?";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $qualification);
if ($stmt->execute()) {
    echo "successful...";
} else {
    echo "Error: " . $stmt->error;
}
$stmt->close();

3. 修正文件格式验证逻辑

原逻辑使用||导致所有文件都能通过验证,改为正确的白名单判断:

// 替换原格式验证代码
$allowed_types = ["jpg", "png", "jpeg", "pdf", "doc", "docx", "gif"];
if (!in_array($imageFileType, $allowed_types)) {
    die("Sorry, only JPG, JPEG, PNG, GIF, PDF, DOC & DOCX files are allowed.");
    $uploadOk = 0;
}

4. 可选:改用JSON存储(更可靠)

序列化数据可读性差且易被破坏,推荐使用JSON格式存储路径数组:

// multiple_upload函数中替换return语句
return json_encode($qualifications);

// View.php中替换反序列化代码
$qualifications = json_decode($row["qualification"], true);

JSON格式兼容性更好,若字段长度不足,MySQL会抛出错误而非静默截断,便于排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:50:37