PHP CRUD更新异常:新图片更新成功但旧图片未从文件夹删除
解决PHP+MySQL CRUD更新时旧图片无法删除的问题
看起来你在更新操作里的几个关键逻辑出错了,导致旧图片删不掉,甚至还误删了刚上传的新图片!我帮你梳理下问题点,然后给出修复后的代码:
核心问题分析
- 变量解析错误:你用单引号包裹路径
'image/$image',PHP不会解析单引号里的变量,实际路径变成了字面量image/$image,unlink自然找不到目标文件。 - 删除对象搞反:你现在执行删除的是刚上传的新图片,而不是数据库里存储的旧图片,完全搞错了操作对象。
- 缺少旧图传递与判断:表单里没传递旧图片的文件名,也没判断用户是否上传了新图片——如果用户没传新图,不该修改
image字段,更不能删除旧图。 - 参数传递隐患:原来的
$_REQUEST['id']等参数是从GET链接获取的,但表单是POST提交,刷新或重新提交会丢失这些参数,应该用隐藏域把id、旧图名存在表单里。 - SQL注入风险:直接把用户输入拼进SQL语句,安全性极低,建议用预处理语句优化。
修复后的update.php代码
<?php include('db.php'); // 注意:先把db.php里的echo "connected successfully";注释掉,否则header跳转失效 if(isset($_POST['UPDATE'])) { // 从表单隐藏域获取关键参数 $id = $_POST['id']; $old_image = $_POST['old_image']; $name = $_POST['name']; $surname = $_POST['surname']; $city = $_POST['city']; $state = $_POST['state']; $target_dir = "image/"; $new_image = $_FILES['image']['name']; // 判断用户是否上传了新图片 if(!empty($new_image)){ $target_file = $target_dir . basename($new_image); // 上传新图片到指定文件夹 move_uploaded_file($_FILES['image']['tmp_name'], $target_file); // 先判断旧图片存在,再删除 if(file_exists($target_dir . $old_image)){ unlink($target_dir . $old_image); } $update_image = $new_image; } else { // 用户没传新图,保留旧图片名 $update_image = $old_image; } // 用预处理语句防止SQL注入 $query = "UPDATE `table` SET `name`=?, `surname`=?, `city`=?, `state`=?, `image`=? WHERE id = ?"; $stmt = mysqli_prepare($con, $query); mysqli_stmt_bind_param($stmt, "sssssi", $name, $surname, $city, $state, $update_image, $id); mysqli_stmt_execute($stmt); header('location:fetch.php'); exit; // 跳转后终止脚本,避免后续代码执行 } // 从GET参数获取初始数据,用于填充表单 $id = $_GET['id']; $name = $_GET['name']; $sname = $_GET['sname']; $city = $_GET['city']; $state = $_GET['state']; $old_image = $_GET['image']; ?> <html> <head> <title> crud operation </title> </head> <body> <table border="1px solid"> <form method="POST" action="" enctype="multipart/form-data"> <!-- 添加隐藏域传递id和旧图片名 --> <input type="hidden" name="id" value="<?php echo $id; ?>"> <input type="hidden" name="old_image" value="<?php echo $old_image; ?>"> <label> name </label> <input type="text" name="name" value="<?php echo $name; ?>" /> <br> <label> Surname </label> <input type="text" name="surname" value="<?php echo $sname; ?>" /><br> <label> city </label> <input type="text" name="city" value="<?php echo $city; ?>" /><br> <label> state </label> <input type="text" name="state" value="<?php echo $state; ?>" /><br> <label> image </label> <input type="file" name="image"/> <!-- 显示当前旧图片,方便用户确认 --> <img src="image/<?php echo $old_image; ?>" style="width:80px; height:80px;" /> <tr> <td><input type="submit" name="UPDATE" value="UPDATE"/></td> </tr> </form> </table> </body> </html>
额外需要调整的细节
- db.php优化:把
echo "connected successfully";注释掉,因为这个输出会导致header()跳转失效(PHP要求header前不能有任何输出)。 - fetch.php链接修正:原来的update链接里
? id=有空格,会导致参数传递失败,改成无空格的格式:<a href='update.php?id=<?php echo $row['id']; ?>&name=<?php echo $row['name']; ?>&sname=<?php echo $row['surname']; ?>&city=<?php echo $row['city']; ?>&state=<?php echo $row['state']; ?>&image=<?php echo $row['image']; ?>'> EDIT </a> - 文件夹权限检查:确保
image文件夹有读写权限(Linux下一般设为755,Windows下无需额外设置),否则unlink和move_uploaded_file都会执行失败。
这样修改后,更新时如果上传新图片,会先把新图传到文件夹,再删除旧图;如果没传新图,就保留旧图,数据库也不会被错误修改。同时解决了变量解析、参数传递、SQL注入等问题。
内容的提问来源于stack exchange,提问作者akash
相关产品推荐
相关产品推荐

