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

为何图片存入数据库的代码无法运行?求助排查

问题描述

花费数小时尝试将用户上传的图片以BLOB(二进制数据)形式存入数据库,但PHP始终无法获取上传文件,一直提示“Please select an image file to upload.”错误。当前逻辑是通过HTML表单获取用户上传的图片,使用AJAX提交数据至PHP后端,由PHP将图片二进制数据存入数据库,但文件始终无法传递到后端。

相关代码

HTML表单代码

<form action="editor.php" class="createBlogForm" autocomplete="off">
    <input type="text" name="title" placeholder="Title" class="title">

    <?php include 'editor.html'; ?>
    </div>
    <div id="catAndSave">
        <select name="categoriesOnCreate" class="categoriesOnCreate">
            <option value="option1">Option 1</option>
            <option value="option2" selected="selected">Anderes</option>
        </select>
        <div id="coverImageDiv">
            <label for="inputTag">
                Select Cover Photo <br/>
                <i class="fa fa-2x fa-camera"></i>
                <input id="inputTag" type="file" name="image"/>
                <br/>
                <span id="imageName"></span>
            </label>
        </div>
          <script>
            let input = document.getElementById("inputTag");
            let imageName = document.getElementById("imageName")
    
            input.addEventListener("change", ()=>{
                let inputImage = document.querySelector("input[type=file]").files[0];
    
                imageName.innerText = inputImage.name;
            })
        </script>
        <button type="submit" class="blogSave" onclick="save();">Save</button>
</form>

AJAX提交代码

<script>
    function save(){
        var xmlhttp = new XMLHttpRequest();
        var content = document.getElementsByClassName('content')[0].innerHTML;
        var title = document.getElementsByClassName('title')[0].value;
        var category = document.getElementsByClassName('categoriesOnCreate')[0].value;
        var data = new FormData();
        data.append("content", content);
        data.append("title", title);
        data.append("category", category);
        const queryString = window.location.search;
        const urlParams = new URLSearchParams(queryString);
        const id = urlParams.get('id');
        xmlhttp.open("POST","editor.php?id=" + id ,true);
        xmlhttp.send(data);
        window.location = "http://192.168.56.104/sodablog/editor.php";
    };
</script>

PHP处理代码

<?php
    ini_set('display_errors', '1');
    ini_set('display_startup_errors', '1');
    error_reporting(E_ALL);
    session_start();
    include 'dbconnect.php';

    $content = $_POST['content'];
    $title = $_POST['title'];
    $category = $_POST['category'];

    date_default_timezone_set('Europe/Rome');
    $date = date("YmdHis"); 

  
    $status = 'error'; 
    if(!empty($_FILES["image"]["name"])) { 
        // Get file info 
        $fileName = basename($_FILES["image"]["name"]); 
        $fileType = pathinfo($fileName, PATHINFO_EXTENSION); 
         
        // Allow certain file formats 
        $allowTypes = array('jpg','png','jpeg','gif'); 
        if(in_array($fileType, $allowTypes)){ 
            $image = $_FILES['image']['tmp_name']; 
            $imgContent = addslashes(file_get_contents($image));
         
            // Insert image content into database 
            $insert = $db->query("INSERT INTO `blog_posts`(`coverImage`) VALUES ('$imgContent');");
             
            if($insert){ 
                $status = 'success'; 
                $statusMsg = "File uploaded successfully."; 
            }else{ 
                $statusMsg = "File upload failed, please try again."; 
            }  
        }else{ 
            $statusMsg = 'Sorry, only JPG, JPEG, PNG, & GIF files are allowed to upload.'; 
        } 
    }else{ 
        $statusMsg = 'Please select an image file to upload.'; 
    } 

 
// Display status message 
echo $statusMsg;

    $sql = "INSERT INTO `blog_posts`(`created_at`, `last_updated_at`, `content`, `title`, `category`) 
    VALUES('$date', '$date', '$content', '$title', '$category');";
    $execution = mysqli_query($conn, $sql) or die("Fehler");
?>

问题排查与解决方法

1. AJAX未添加上传文件到FormData

核心问题是AJAX创建FormData后,没有将用户选择的图片文件加入其中,导致后端无法获取文件。修改AJAX代码:

function save(event){
    // 阻止表单默认提交行为,避免页面提前跳转
    event.preventDefault();
    var xmlhttp = new XMLHttpRequest();
    var content = document.getElementsByClassName('content')[0].innerHTML;
    var title = document.getElementsByClassName('title')[0].value;
    var category = document.getElementsByClassName('categoriesOnCreate')[0].value;
    // 获取用户选择的图片文件
    var imageFile = document.getElementById('inputTag').files[0];
    
    var data = new FormData();
    data.append("content", content);
    data.append("title", title);
    data.append("category", category);
    // 将图片文件加入FormData
    if(imageFile) {
        data.append("image", imageFile);
    }
    
    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const id = urlParams.get('id');
    
    xmlhttp.open("POST","editor.php?id=" + id ,true);
    // 无需手动设置Content-Type,浏览器会自动处理multipart/form-data格式
    xmlhttp.send(data);
    
    // 等待AJAX请求完成后再跳转页面
    xmlhttp.onload = function() {
        if(xmlhttp.status === 200) {
            window.location = "http://192.168.56.104/sodablog/editor.php";
        }
    };
};

2. HTML表单缺少文件上传必需属性

上传文件的表单必须设置enctype="multipart/form-data",否则浏览器无法正确编码文件数据。修改form标签:

<form action="editor.php" class="createBlogForm" autocomplete="off" enctype="multipart/form-data">

3. 修复按钮的默认提交行为

原按钮为type="submit",点击会触发表单默认提交,导致AJAX请求被中断。可通过两种方式修复:

  • 方法一:修改按钮类型为button
<button type="button" class="blogSave" onclick="save(event);">Save</button>
  • 方法二:在save函数中阻止默认行为(已在上面AJAX代码中实现)

4. 修复PHP代码的SQL注入风险与逻辑问题

原代码存在严重SQL注入风险,且两次插入数据会生成两条独立记录,需合并为一次插入,并使用预处理语句:

<?php
ini_set('display_errors', '1');
ini_set('display_startup_errors', '1');
error_reporting(E_ALL);
session_start();
include 'dbconnect.php';

// 安全获取POST参数,避免未定义索引错误
$content = $_POST['content'] ?? '';
$title = $_POST['title'] ?? '';
$category = $_POST['category'] ?? '';

date_default_timezone_set('Europe/Rome');
$date = date("YmdHis"); 

$status = 'error'; 
$statusMsg = 'Please select an image file to upload.';

// 检查文件是否上传成功
if(!empty($_FILES["image"]["name"]) && $_FILES["image"]["error"] === UPLOAD_ERR_OK) { 
    $fileName = basename($_FILES["image"]["name"]); 
    $fileType = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); 
     
    $allowTypes = array('jpg','png','jpeg','gif'); 
    if(in_array($fileType, $allowTypes)){ 
        $imgContent = file_get_contents($_FILES['image']['tmp_name']);
        // 使用预处理语句防止SQL注入,合并图片与文章数据的插入操作
        $stmt = $conn->prepare("INSERT INTO `blog_posts`(`coverImage`, `created_at`, `last_updated_at`, `content`, `title`, `category`) VALUES (?, ?, ?, ?, ?, ?)");
        $stmt->bind_param("ssssss", $imgContent, $date, $date, $content, $title, $category);
         
        if($stmt->execute()){ 
            $status = 'success'; 
            $statusMsg = "File uploaded successfully."; 
        }else{ 
            $statusMsg = "File upload failed, please try again."; 
        }  
        $stmt->close();
    }else{ 
        $statusMsg = 'Sorry, only JPG, JPEG, PNG, & GIF files are allowed to upload.'; 
    } 
}elseif($_FILES["image"]["error"] !== UPLOAD_ERR_NO_FILE) {
    // 处理其他上传错误
    $statusMsg = 'File upload error: ' . $_FILES["image"]["error"];
}

echo $statusMsg;
?>

注:确保dbconnect.php返回的mysqli连接对象为$conn,保持代码中连接对象的一致性。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:05:29