PHP表单上传文件插入MySQL报未定义数组键警告问题求解
问题根因
触发这两组警告的核心原因是PHP后端读取不到$_FILES超全局变量里的course_image、course_video键,常见触发场景有4种:
- 前端表单漏加
enctype="multipart/form-data"属性。默认表单编码为application/x-www-form-urlencoded,仅支持普通文本字段传输,不会携带文件二进制数据,此时$_FILES数组不会生成对应文件字段的键,直接访问会先报未定义数组键警告,后续读取文件临时路径、文件名等子项时,因为前置取值为null,就会触发访问null值偏移的错误。 - 后端未做存在性校验就直接硬读数组键。不管是前端漏传、上传异常、还是键名拼写错误,没有
isset()/array_key_exists()判断直接访问数组键必然触发警告。 - 前后端字段名不匹配。比如前端文件上传input的
name属性写为courseImg/video,后端硬编码读取course_image/course_video,键名不匹配自然读不到值。 - PHP配置限制导致请求被截断。如果
upload_max_filesize、post_max_size设置值小于上传文件大小,PHP会直接截断请求体,$_FILES不会生成对应字段键。
修复步骤
1. 修正前端表单配置
首先检查表单标签,必须配置为post提交+文件上传专用编码,同时核对两个文件字段的name属性和后端读取的键名完全一致:
<!-- 错误写法:漏enctype、用get提交都会导致文件传不上去 <form action="insert.php" method="get"> --> <!-- 正确写法 --> <form action="insert.php" method="post" enctype="multipart/form-data"> <!-- 其他普通课程字段:课程名、简介、分类等省略 --> <!-- 课程图片字段,name必须和后端键名一致 --> <label>课程封面图</label> <input type="file" name="course_image" accept="image/*" required> <!-- 课程视频字段,name必须和后端键名一致 --> <label>课程视频</label> <input type="file" name="course_video" accept="video/*" required> <button type="submit">提交课程</button> </form>
2. 后端增加前置校验,替换原来直接读$_FILES的逻辑
找到insert.php的154行附近的代码,不要直接读取$_FILES['course_image']、$_FILES['course_video'],先做存在性和上传状态校验:
// 提前初始化存储路径变量,避免后续数据库插入时出现未定义变量问题 $course_image = ''; $course_video = ''; // 提前在站点根目录创建upload/course文件夹,给读写权限,用于存上传的文件 $uploadBasePath = $_SERVER['DOCUMENT_ROOT'].'/netadem/upload/course/'; // 校验课程图片上传状态 if (isset($_FILES['course_image']) && $_FILES['course_image']['error'] === UPLOAD_ERR_OK) { // 校验文件后缀,避免非法文件上传 $imageExt = strtolower(pathinfo($_FILES['course_image']['name'], PATHINFO_EXTENSION)); $allowImageExt = ['jpg','jpeg','png','gif','webp']; if (!in_array($imageExt, $allowImageExt)) { die("课程图片仅支持jpg、png、webp格式"); } // 生成唯一文件名,避免重名覆盖 $imageSaveName = uniqid('course_img_').'.'.$imageExt; $course_image = 'upload/course/'.$imageSaveName; // 移动临时文件到存储目录 move_uploaded_file($_FILES['course_image']['tmp_name'], $uploadBasePath.$imageSaveName); } else { // 上传失败直接抛出对应错误 $errMsg = [ UPLOAD_ERR_INI_SIZE => '课程图片超过php.ini配置的上传大小限制', UPLOAD_ERR_FORM_SIZE => '课程图片超过表单限制大小', UPLOAD_ERR_PARTIAL => '课程图片上传不完整', UPLOAD_ERR_NO_FILE => '未上传课程图片', UPLOAD_ERR_NO_TMP_DIR => '服务器临时目录不存在', UPLOAD_ERR_CANT_WRITE => '服务器无文件写入权限' ]; $errCode = $_FILES['course_image']['error'] ?? 999; die($errMsg[$errCode] ?? '课程图片上传未知错误'); } // 课程视频校验逻辑和图片一致 if (isset($_FILES['course_video']) && $_FILES['course_video']['error'] === UPLOAD_ERR_OK) { $videoExt = strtolower(pathinfo($_FILES['course_video']['name'], PATHINFO_EXTENSION)); $allowVideoExt = ['mp4','mov','avi','mkv']; if (!in_array($videoExt, $allowVideoExt)) { die("课程视频仅支持mp4、mov格式"); } $videoSaveName = uniqid('course_video_').'.'.$videoExt; $course_video = 'upload/course/'.$videoSaveName; move_uploaded_file($_FILES['course_video']['tmp_name'], $uploadBasePath.$videoSaveName); } else { $errMsg = [ UPLOAD_ERR_INI_SIZE => '课程视频超过php.ini配置的上传大小限制', UPLOAD_ERR_FORM_SIZE => '课程视频超过表单限制大小', UPLOAD_ERR_PARTIAL => '课程视频上传不完整', UPLOAD_ERR_NO_FILE => '未上传课程视频', UPLOAD_ERR_NO_TMP_DIR => '服务器临时目录不存在', UPLOAD_ERR_CANT_WRITE => '服务器无文件写入权限' ]; $errCode = $_FILES['course_video']['error'] ?? 999; die($errMsg[$errCode] ?? '课程视频上传未知错误'); } // 后续数据库插入逻辑,直接使用上面生成的$course_image、$course_video变量存到MySQL对应字段即可 // 注意数据库插入要用预处理语句,避免SQL注入
3. 调整PHP上传配置(大文件上传必改)
如果上传的视频文件较大,打开xampp的php.ini配置文件,修改以下参数,改完重启Apache服务生效:
file_uploads = On ; 单文件最大允许大小,根据自身需求调整 upload_max_filesize = 1024M ; post请求总大小,必须比upload_max_filesize大50M以上,留足其他表单字段空间 post_max_size = 1100M ; 脚本最大执行时间,大文件上传需要调长 max_execution_time = 600 max_input_time = 600 memory_limit = 512M
内容的提问来源于stack exchange,提问作者Sam Akins
相关产品推荐
相关产品推荐

