CodeIgniter中仅更新文本字段时旧图片被删除的问题
解决CodeIgniter中仅更新文本时旧图片记录被删除的问题
我来帮你搞定这个头疼的问题!核心原因是你当前的文件上传判断逻辑有问题,而且更新数据时没有区分“是否上传了新图片”,导致没传图的时候错误地把图片字段清空了。
问题分析
你代码里的if($_FILES['file_name']!="")判断完全不对——当没有上传文件时,$_FILES['file_name']是一个数组而不是空字符串,这个条件的判断逻辑根本不成立。更关键的是,如果你在构建更新数据时,不管有没有新图都把file_name字段加进去,没传图的时候就会赋值为空,直接覆盖数据库里的旧图片记录。
具体解决方案
1. 修正文件上传的判断逻辑
不要直接判断$_FILES是否为空,而是检查文件上传的错误状态,或者用CodeIgniter官方的上传类(更规范):
// 原生PHP判断是否有有效文件上传 if ($_FILES['file_name']['error'] == UPLOAD_ERR_OK) { // 这里处理图片上传逻辑 } // 推荐:用CodeIgniter上传类处理 $this->load->library('upload'); $config['upload_path'] = './photo/uploads/'; $config['allowed_types'] = 'gif|jpg|png|jpeg'; // 按需调整允许的图片类型 $config['max_size'] = 2048; // 限制最大2MB,按需修改 $this->upload->initialize($config); if ($this->upload->do_upload('file_name')) { // 上传成功,获取文件信息 $upload_data = $this->upload->data(); $file_name = $upload_data['file_name']; } else { // 区分“没上传文件”和“上传失败”,这里只处理没传图的情况 $upload_error = $this->upload->display_errors(); // 如果是“没有选择文件”的错误,就标记没有新图 if (strpos($upload_error, 'You did not select a file to upload') !== false) { $file_name = null; } else { // 其他上传错误可以在这里处理,比如提示用户 } }
2. 只在有新图片时更新图片字段
构建更新数据数组时,只有成功上传新图片后,才把file_name字段加入数组,否则不包含这个字段,这样数据库就不会修改原来的图片记录:
// 先初始化更新数据,加入所有需要更新的文本字段 $update_data = array( 'title' => $this->input->post('title'), // 替换成你的实际文本字段名 'content' => $this->input->post('content'), 'author' => $this->input->post('author'), // 其他文本字段... ); // 如果有新图片上传,才添加file_name字段到更新数组 if (isset($file_name) && !empty($file_name)) { $update_data['file_name'] = $file_name; // 可选:如果需要删除旧图片,可以在这里根据$id查询旧图片路径然后删除 $old_image = $this->db->get_where('your_blog_table', array('id' => $id))->row()->file_name; if (!empty($old_image)) { unlink('./photo/uploads/' . $old_image); } } // 执行数据库更新 $this->db->where('id', $id); $this->db->update('your_blog_table', $update_data); // 替换成你的实际表名
3. 完整修改后的控制器示例
把这些逻辑整合到你的blog_walk_update函数里:
function blog_walk_update($id){ $this->_checkAuthorized(self::CATEGORY_ID,'w'); $_POST['id'] = $id; $file_name = null; // 初始化上传类 $this->load->library('upload'); $config['upload_path'] = './photo/uploads/'; $config['allowed_types'] = 'jpg|png|jpeg'; $config['max_size'] = 2048; $this->upload->initialize($config); // 尝试上传文件 if ($this->upload->do_upload('file_name')) { $upload_data = $this->upload->data(); $file_name = $upload_data['file_name']; // 删除旧图片 $old_image = $this->db->get_where('blog_walk', array('id' => $id))->row()->file_name; if (!empty($old_image)) { unlink('./photo/uploads/' . $old_image); } } else { // 处理无文件上传的情况 $error_msg = $this->upload->display_errors(); if (strpos($error_msg, 'You did not select a file') === false) { // 这里可以添加上传失败的提示逻辑 $this->session->set_flashdata('error', $error_msg); } } // 构建更新数据 $update_data = array( 'title' => $this->input->post('title'), 'description' => $this->input->post('description'), // 其他你的文本字段... ); // 只有成功上传新图才更新file_name字段 if ($file_name) { $update_data['file_name'] = $file_name; } // 执行更新 $this->db->where('id', $id); $this->db->update('blog_walk', $update_data); // 跳转或提示 $this->session->set_flashdata('success', '更新成功'); redirect('blog_walk'); }
关键要点
- 永远不要直接判断
$_FILES是否为空字符串,要通过error状态或者CodeIgniter上传类来准确判断是否有有效文件上传。 - 更新数据库时,只在有新数据需要修改时才将对应字段加入更新数组,避免不必要的字段覆盖。
内容的提问来源于stack exchange,提问作者Shah Abbas
相关产品推荐
相关产品推荐

