PHP根据下拉选择执行表单上传/删除操作及报错解决
问题现象
搭建的文件操作表单包含文件选择控件、操作类型下拉框(上传/删除文件),选择「delete file」提交后出现以下报错:
Warning: Undefined array key "fileToDelete" in C:\xampp\htdocs\fileuploadoperations\delete.php on line 5
Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\fileuploadoperations\delete.php on line 5
Warning: Undefined array key "fileToDelete" in C:\xampp\htdocs\fileuploadoperations\delete.php on line 6
Warning: Trying to access array offset on value of type null in C:\xampp\htdocs\fileuploadoperations\delete.php on line 6
报错原因
- 表单文件字段名不匹配:前端文件选择控件的
name属性是fileToUpload,但delete.php中读取文件用的键名是fileToDelete,两者不一致 - 跳转逻辑丢失请求数据:loadPage.php中用
header("Location: xxx.php")做的是GET重定向,原表单提交的POST参数、上传的文件数据不会被带到跳转后的页面,导致delete.php根本接收不到文件数据 - 未做参数存在性判断:代码直接读取
$_FILES、$_POST中的字段,没有提前判断键是否存在,参数缺失时直接触发警告 - 提交按钮判断逻辑错误:表单中提交按钮没有设置
name="Delete"的属性,delete.php中isset($_POST["Delete"])的判断永远不会成立,删除逻辑根本不会执行 - 语法不规范:原代码CSS、HTML中误用了
//作为注释(这是PHP/JS的单行注释语法),CSS注释需要用/* 注释内容 */,HTML注释需要用<!-- 注释内容 -->,错误的注释会导致页面样式、渲染异常;另外原CSS还存在box-size、text-color等不存在的属性,会导致样式失效。
修复步骤
- 废弃中间跳转逻辑,避免重定向丢失POST和文件数据:直接在表单提交的处理文件中做操作分支判断,不需要跳转到单独的upload.php/delete.php
- 统一文件字段名,前后端读取的键名保持一致
- 所有超全局变量(
$_POST/$_FILES)取值前必须用isset()判断键是否存在,避免非法访问报错 - 修正提交按钮的判断逻辑,匹配实际表单字段
- 修正所有不符合规范的注释、CSS属性语法
修正后代码
前端表单页代码
<?php include "dbconfig.php"; // 引入数据库连接配置 ?> <html> <head> <title>file upload operations</title> <style> * { box-sizing: border-box; } form { display: block; text-align: center; margin: 30px; padding: 30px; color: black; font-weight: bold; } body { background-color: #CCCCFF; display: flex; align-items: center; justify-content: center; margin: 0 auto; height: 100vh; color: white; } input[type=submit] { background-color: #FF6600; color: white; padding: 12px 20px; border: none; border-radius: 4px; cursor: pointer; } input[type=submit]:hover { background-color: #45a049; } </style> </head> <body> <div class="container"> <form action="handle.php" method="post" enctype="multipart/form-data" name="theForm" id="theForm"> <input type="file" name="fileToOperate" id="fileToOperate"><br><br><br><br> <select name="operationType"> <option value="upload">upload file</option> <option value="delete">delete file</option> </select><br><br><br><br><br><br> <input type="submit" name="submit" value="提交" /> <input type="reset" value="Cancel"> </form> </div> </body> </html>
统一处理文件handle.php(替换原loadPage.php、分离的upload/delete逻辑)
<?php $target_dir = "uploads/"; // 校验是否为合法表单提交 if (!isset($_POST['submit'], $_POST['operationType'])) { exit("非法请求"); } // 自动创建上传目录如果不存在 if (!is_dir($target_dir)) { mkdir($target_dir, 0755, true); } $operation = $_POST['operationType']; switch($operation) { case "upload": // 校验文件上传状态 if (!isset($_FILES['fileToOperate']) || $_FILES['fileToOperate']['error'] !== UPLOAD_ERR_OK) { exit("请选择要上传的文件"); } $target_file = $target_dir . basename($_FILES["fileToOperate"]["name"]); if (move_uploaded_file($_FILES["fileToOperate"]["tmp_name"], $target_file)) { echo "文件 ". htmlspecialchars(basename($_FILES["fileToOperate"]["name"])). " 上传成功"; } else { echo "文件上传失败,请检查目录权限"; } break; case "delete": // 校验待删除文件参数 if (!isset($_FILES['fileToOperate']) || $_FILES['fileToOperate']['error'] !== UPLOAD_ERR_OK) { exit("请选择要删除的对应文件"); } $target_file = $target_dir . basename($_FILES["fileToOperate"]["name"]); if (!file_exists($target_file)) { exit("目标文件不存在"); } if (unlink($target_file)) { echo $target_file . " 已成功删除"; } else { echo $target_file . " 删除失败,请检查目录权限"; } break; default: echo "请选择正确的操作类型"; break; } ?>
补充说明:如果需要保留upload.php、delete.php的分离结构,不能用header跳转,需要在loadPage.php中用
include引入对应文件,同时确保表单提交的所有数据能被正确读取;另外删除服务器已有文件的场景更合理的逻辑是直接传递服务器上的文件名列表供用户选择,不需要用户本地选择对应文件。
内容的提问来源于stack exchange,提问作者Priya Tiwari

