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

PHP视频上传功能报错:courses_id无默认值(主键自增仍报错)

问题解决:自增主键courses_id报无默认值错误

核心问题分析

你遇到的错误本质是代码中无条件执行了courses表的INSERT操作(页面加载时就执行,而非仅表单提交时),同时可能伴随数据库表结构或SQL模式的配置问题,导致自增主键未自动生成值。

分步解决方法

1. 修复代码中无条件执行INSERT的逻辑

原代码中courses表的插入操作直接暴露在全局作用域,每次加载页面(包括GET请求打开表单)都会执行一次无效INSERT,此时$_POST为空,触发数据库报错。将插入逻辑包裹在表单提交判断内:

$config = require 'config.php';

// 仅当表单提交时才执行后续逻辑
if (isset($_POST['submit'])) {
    // 处理课程信息插入
    $courses_name = $_POST['courses_name'] ?? '';
    $courses_description = $_POST['courses_description'] ?? '';
    $courses_category = isset($_POST['courses_category']) ? implode(',', $_POST['courses_category']) : '';

    // 验证必填字段
    if (empty($courses_name) || empty($courses_description)) {
        $_SESSION['message'] = "课程名称和描述不能为空";
    } else {
        $query = Connection::make($config['database'])->prepare("INSERT INTO courses(courses_name, courses_description, courses_category) VALUES(?, ?, ?)");
        $query->bindParam(1, $courses_name, PDO::PARAM_STR);
        $query->bindParam(2, $courses_description, PDO::PARAM_STR);
        $query->bindParam(3, $courses_category, PDO::PARAM_STR);
        $query->execute();
    }

    // 文件上传逻辑(保持原有逻辑,修复SQL注入)
    $maxsize= 104857600; //100MB in Bytes

    if (isset($_FILES['file']['name']) && $_FILES['file']['name'] !=''){
        $name = $_FILES['file']['name'];
        $target_dir = "videos/";
        $target_file = $target_dir.$name;

        $extension = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
        $extension_arr = array("mp4", "avi", "3gp", "mov", "mpeg");

        if (in_array($extension, $extension_arr)){
            if ($_FILES['file']['size'] >=$maxsize){
                $_SESSION['message'] = "文件过大,必须小于100MB";
            } else{
                if (move_uploaded_file($_FILES['file']['tmp_name'],$target_file)){
                    // 修复SQL注入:使用参数绑定而非字符串拼接
                    $stmt = Connection::make($config['database'])->prepare("INSERT INTO videos(video_name,video_location) VALUES(?, ?)");
                    $stmt->bindParam(1, $name, PDO::PARAM_STR);
                    $stmt->bindParam(2, $target_file, PDO::PARAM_STR);
                    $stmt->execute();

                    $_SESSION['message'] = "上传成功";
                }
            }
        } else{
            $_SESSION['message'] = "无效的文件格式";
        }
    }else{
        $_SESSION['message'] = "请选择一个文件";
    }
}

2. 确认数据库表结构正确性

执行以下SQL检查courses表结构:

DESCRIBE courses;

确保courses_id字段满足:

  • 类型为INT
  • 标记为PRIMARY KEY
  • 包含AUTO_INCREMENT属性

如果缺少自增属性,执行修改语句:

ALTER TABLE courses MODIFY COLUMN courses_id INT PRIMARY KEY AUTO_INCREMENT;

3. 调整MariaDB的SQL_MODE配置

执行SQL查看当前模式:

SELECT @@SQL_MODE;

若结果包含NO_AUTO_VALUE_ON_ZERO,需移除该模式(它会阻止自增字段自动生成值):

  • 临时修改:SET GLOBAL SQL_MODE = '替换为你的其他模式,去掉NO_AUTO_VALUE_ON_ZERO';
  • 永久修改:修改my.cnf(Linux)或my.ini(Windows)中的sql_mode配置项,重启MariaDB。

4. 修复复选框多分类提交问题

原表单中复选框name均为courses_category,仅能提交最后一个选中值。修改为数组格式以支持多选:

<input name="courses_category[]" type="checkbox" class="btn-check" id="btncheck1" autocomplete="off" value="html">
<label class="btn btn-outline-primary" for="btncheck1">Html</label>

<input name="courses_category[]" type="checkbox" class="btn-check" id="btncheck2" autocomplete="off" value="php">
<label class="btn btn-outline-primary" for="btncheck2">Php</label>

<input name="courses_category[]" type="checkbox" class="btn-check" id="btncheck3" autocomplete="off" value="css">
<label class="btn btn-outline-primary" for="btncheck3">CSS</label>

<input name="courses_category[]" type="checkbox" class="btn-check" id="btncheck4" autocomplete="off" value="java">
<label class="btn btn-outline-primary" for="btncheck4">Java</label>

在PHP中用implode将数组转为字符串存储(如代码第一步所示)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 06:31:21