CodeIgniter3多输入多文件上传异常:仅单个文件存入数据库求助
多组文件上传问题排查与修复
问题描述
实现多组other_title与other_file上传功能时,Controller循环处理仅能存入单个文件,其余文件无法正常写入数据库。
用户提供代码
View代码
<!-- Modal --> <div class="form-row"> <div class="form-group col-md-12"> <label for="otitle">Other</label> <div class="form-row add-container"> <div class="col-6"> <input type="text" class="form-control" id="" name="other_title[]" placeholder="Input title" multiple> </div> <div class="col-5"> <input class="form-control" type="file" name="other_file[]" id="" multiple> </div> <div class="col-auto"> <a class="btn add-comp" style="border: 0; padding: 10px;"><i class="fa fa-plus" style="color: #006CF8;"></i></a> </div> </div> </div> </div> <!-- End Modal -->
Controller代码
public function actionBible($type, $id = null) { $id_kategori = $this->input->post('id_kategori'); $id_kategori = $id_kategori == NULL ? $this->input->post('nama_kategori') : $id_kategori; $data = array( 'nama_bible' => $this->input->post('nama_bible'), 'description' => $this->input->post('description'), 'datasheet_title' => $this->input->post('datasheet_title'), 'manual_title' => $this->input->post('manual_title'), 'id_kategori' => $id_kategori, 'created_by' => $this->session->userdata('nama_user'), ); $folderUpload = "./uploads/bible/"; $files = $_FILES; // datasheet $namaFile = $files['file']['name']; $lokasiTmp = $files['file']['tmp_name']; // # kita tambahkan uniqid() agar nama gambar bersifat unik $namaBaru = uniqid() . '-' . $namaFile; $lokasiBaru = "{$folderUpload}/{$namaBaru}"; move_uploaded_file($lokasiTmp, $lokasiBaru); // manual $namaFileManual = $files['manual_file']['name']; $lokasiTmpManual = $files['manual_file']['tmp_name']; // # kita tambahkan uniqid() agar nama gambar bersifat unik $namaBaruManual = uniqid() . '-' . $namaFileManual; $lokasiBaruManual = "{$folderUpload}/{$namaBaruManual}"; move_uploaded_file($lokasiTmpManual, $lokasiBaruManual); // datasheet $ktp = array('file' => $namaBaru); if ($namaFile != NULL) { $data = array_merge($data, $ktp); } // manual $manual = array('manual' => $namaBaruManual); if ($namaFileManual != NULL) { $data = array_merge($data, $manual); } // var_dump($data); if ($type == 'add') { $store = $this->db->insert('tb_bible', $data); if ($store) { // attachments $getLastId = $this->db->order_by('id_bible', 'DESC')->limit(1)->get('tb_bible')->row_array(); $files = $_FILES; $jumlahFile = count($files['other_file']['name']); $other_title = $this->input->post('other_title'); for ($i = 0; $i < $jumlahFile; $i++) { $data = array( 'id_bible' => $getLastId['id_bible'], 'id_other' => $this->input->post('id_other'), 'other_title' => $other_title[$i], 'created_at' => date('Y-m-d H:i:s') ); $folderUpload = "./uploads/upnormal/"; $files = $_FILES; $namaFileOther = $files['other_file']['name'][$i]; $lokasiTmpOther = $files['other_file']['tmp_name'][$i]; // # kita tambahkan uniqid() agar nama gambar bersifat unik $namaBaruOther = uniqid() . '-' . $namaFileOther; $lokasiBaruOther = "{$folderUpload}/{$namaBaruOther}"; move_uploaded_file($lokasiTmpOther, $lokasiBaruOther); $other = array('other' => $namaBaruOther); // mengambil nama baru dan di upload ke dalam databases if ($namaFileOther != NULL) { $data = array_merge($data, $other); $this->db->insert('tb_other_bible', $data); } } } } elseif ($type == 'edit') { $this->db->update('tb_bible', $data, ['id_bible' => $this->input->post('id_bible')]); } else { $data = array( 'delete' => 1 ); $this->db->update('tb_bible', $data, ['id_bible' => decrypt_url($id)]); } $this->session->set_flashdata('messageAlert', $this->messageAlert('success', "Data $type")); redirect('bible/guide'); }
问题根源
- 表单缺失
enctype="multipart/form-data":这是文件上传的必要属性,未添加时后端仅能接收第一个文件,其余文件无法被正确传递。 - 循环次数依赖文件数量:以
other_file的数量作为循环依据,若存在填写标题但未选择文件的情况,对应记录会被跳过;同时若标题数量多于文件数量,部分标题无法被处理。 - 循环内重复赋值冗余代码:
$files = $_FILES在循环内重复定义,无实际作用且易混淆逻辑。 - 缺乏上传错误处理:未校验
move_uploaded_file的执行结果,若文件上传失败,会导致数据库存入无效路径或直接跳过记录。 - 手动操作
$_FILES风险:未使用CodeIgniter内置的上传类,无法利用框架的安全校验与错误处理机制。
修复方案
1. 修改View表单
确保包含文件上传的表单添加enctype="multipart/form-data"属性:
<form method="post" action="<?= site_url('bible/actionBible/add') ?>" enctype="multipart/form-data"> <!-- 原有表单内容 --> </form>
2. 修改Controller代码
public function actionBible($type, $id = null) { $id_kategori = $this->input->post('id_kategori'); $id_kategori = $id_kategori == NULL ? $this->input->post('nama_kategori') : $id_kategori; $data = array( 'nama_bible' => $this->input->post('nama_bible'), 'description' => $this->input->post('description'), 'datasheet_title' => $this->input->post('datasheet_title'), 'manual_title' => $this->input->post('manual_title'), 'id_kategori' => $id_kategori, 'created_by' => $this->session->userdata('nama_user'), ); $folderUpload = "./uploads/bible/"; // 初始化上传类配置 $this->load->library('upload'); // 处理datasheet文件 if (!empty($_FILES['file']['name'])) { $config['upload_path'] = $folderUpload; $config['allowed_types'] = '*'; // 根据需求限制文件类型,如'pdf|doc' $config['file_name'] = uniqid() . '-' . $_FILES['file']['name']; $this->upload->initialize($config); if ($this->upload->do_upload('file')) { $uploadData = $this->upload->data(); $data['file'] = $uploadData['file_name']; } } // 处理manual文件 if (!empty($_FILES['manual_file']['name'])) { $config['upload_path'] = $folderUpload; $config['allowed_types'] = '*'; $config['file_name'] = uniqid() . '-' . $_FILES['manual_file']['name']; $this->upload->initialize($config); if ($this->upload->do_upload('manual_file')) { $uploadData = $this->upload->data(); $data['manual'] = $uploadData['file_name']; } } if ($type == 'add') { $store = $this->db->insert('tb_bible', $data); if ($store) { $getLastId = $this->db->insert_id(); // 直接获取刚插入的ID,比查最新记录更可靠 $otherTitles = $this->input->post('other_title'); $otherFiles = $_FILES['other_file']; $folderOther = "./uploads/upnormal/"; // 以标题数量作为循环依据,确保每组标题都被处理 foreach ($otherTitles as $index => $title) { // 跳过空标题 if (empty(trim($title))) continue; $insertData = array( 'id_bible' => $getLastId, 'id_other' => $this->input->post('id_other'), 'other_title' => $title, 'created_at' => date('Y-m-d H:i:s') ); // 处理对应文件 if (!empty($otherFiles['name'][$index])) { $config['upload_path'] = $folderOther; $config['allowed_types'] = '*'; $config['file_name'] = uniqid() . '-' . $otherFiles['name'][$index]; $this->upload->initialize($config); if ($this->upload->do_upload('other_file', $index)) { // 指定上传索引 $uploadData = $this->upload->data(); $insertData['other'] = $uploadData['file_name']; } } // 无论是否有文件,只要有标题就插入数据库 $this->db->insert('tb_other_bible', $insertData); } } } elseif ($type == 'edit') { $this->db->update('tb_bible', $data, ['id_bible' => $this->input->post('id_bible')]); } else { $data = array('delete' => 1); $this->db->update('tb_bible', $data, ['id_bible' => decrypt_url($id)]); } $this->session->set_flashdata('messageAlert', $this->messageAlert('success', "Data $type")); redirect('bible/guide'); }
关键修复点说明
- 使用
$this->db->insert_id()获取刚插入的ID,比查询最新记录更高效可靠。 - 以
other_title的数量作为循环依据,确保每组标题都被处理,避免遗漏。 - 引入CodeIgniter上传类,实现安全的文件上传与错误处理。
- 移除冗余的重复赋值代码,简化逻辑。
- 允许无文件但有标题的记录存入数据库(可根据需求调整)。
内容的提问来源于stack exchange,提问作者ucanggg2021
相关产品推荐
相关产品推荐

