Codeigniter - 无法从多个文件输入上传文件

Codeigniter - Not able to upload files from multiple file inputs

我有一个多步骤表单,它有很多输入字段,包括多个文件输入,其中一些是动态生成的 JavaScript.In 表单的一个部分,用户可以上传多个文件。我能够将表单数据插入数据库,但无法上传用户 upload.I 正在使用 AJAX 上传表单数据和文件的那些多个文档文件。这是我的控制器代码,

<?php

defined('BASEPATH') or exit('No direct script access allowed');

class Employee extends MY_Controller
{

    public function index()
    {
        $data['title'] = 'employees';
        $this->view('employees/view_employee_view', $data);
    }

    public function save()
    {
        $req = $this->input->post();

            // Some other code here

            // First upload the profile picture
            if (!empty($_FILES['emp_photo']) AND $_FILES["emp_photo"]["error"] == 0) {

                // Upload employee photo
                $emp_photo_data = $this->upload_file(EMP_PHOTOS_FOLDER, 'emp_photo');

                if (array_key_exists('error', $emp_photo_data)) {
                    $this->response(['success'=>false, 'msg' => '<b>File upload failed!Try again</b>', 'data'=> ''], 500);
                    exit();
                }
                else {
                    $employee['emp_photo'] = $emp_photo_data['file_name'];
                }
            }
            
            $this->db->trans_start();

            $emp_id = $this->Employee_model->save($employee);

            // Save edu details of employee
            $this->add_edu_details($emp_id);

            // Upload employee documents
            $doc_details = $this->upload_emp_docs($emp_id); //<-- Here is the problem
            
            if (is_string($doc_details)) {
                // it's an error
                $this->response(['success' => false, 'msg' => '<b>Employee documents upload failed!</b>', 'data' => $doc_details]);
                $this->db->trans_rollback(); 
                exit();
            }
            else{
                if ($doc_details === FALSE) {
                    // Error occured - rollback
                    $this->response(['success' => false, 'msg' => '<b>Employee documents upload failed!</b>', 'data' => '']);
                    $this->db->trans_rollback();
                    exit();
                }
            }

    }


    private function upload_emp_docs($emp_id)
    {
        $counts = $this->input->post('emp_docs_count');

        $req = $this->input->post();
        
        $data = [];
        for ($i = 1; $i <= $counts; $i++) { 
            
            if (!empty($_FILES['emp_doc_' . $i])) {
                $res = $this->upload_file(EMP_DOCS_FOLDER, 'emp_doc_' . $i, 'pdf');
                $done = move_uploaded_file($_FILES["emp_doc_" . $i]["tmp_name"], EMP_PHOTOS_FOLDER . md5(time()) . '.jpg');
                if (array_key_exists('error', $res)) {
                    return $res['error']; // return error string
                }
                else {
                    $data[$i] = ["emp_id" => $emp_id, 'file_name' => $res["file_name"], 'doc_type'=> $req["emp_doc_type_{$i}"] ];
                }
            }
        }

        if (!empty($data)) {
            $done = $this->Emp_doc_model->save($data);
            return !empty($done) ? TRUE : FALSE;
        }
        else {
            return FALSE;
        }
    }

}

这里是 MY_Controller.php 中实际执行上传任务的代码

public function upload_file($dir, $input, $allowed_types = 'jpeg|jpg|png')
    {
        $config['upload_path']   = $dir;
        $config['allowed_types'] = !empty($allowed_types) ? $allowed_types : 'jpeg|jpg|png';
        $config['max_size']      = 0;
        $config['max_width']     = 0;
        $config['max_height']    = 0;
        $config['file_name']     = md5(time() . rand(1, 1000));

        $this->load->library('upload', $config);

        if (!$this->upload->do_upload($input)) {
            return array('error' => $this->upload->display_errors());
        } else {
            $data = $this->upload->data();

            // If it is image then resize it to reduce the image file size
            if ($data['is_image']) {
                $this->resize_image($data['full_path']);
            }

            return $data;
        }
    }

在一个部分中,用户可以 select 一张个人资料照片,我可以使用上面的代码上传该文件,但是我无法找到为什么当我尝试上传多个文件时它不起作用.

这是该部分的 HTML 代码

<div class="col upload-area">
<div class="input-group">
   <a class="btn bg-grey btn-block" id="add-file-group">ADD FILE</a>
</div>
<input type="hidden" id="emp_docs_count" name="emp_docs_count" value="1">
<div class="row clearfix file-upload-group">
   <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
      <div class="form-group">
         <div class="form-line">
            <input name="emp_doc_1" type="file" class="form-control">
         </div>
      </div>
   </div>
   <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
      <div class="form-group">
         <div class="form-line">
            <select name="emp_doc_type_1" id="emp_doc_type_1" class="form-control show-tick selectpicker" title="Choose one of the following...">
               <option value="<?= OFFER_LETTER ?>"><?= OFFER_LETTER ?></option>
               <option value="<?= APPOINT_LETTER ?>"><?= APPOINT_LETTER ?></option>
               <option value="<?= CONF_LETTER ?>"><?= CONF_LETTER ?></option>
               <option value="<?= APP_LETTER_1 ?>"><?= APP_LETTER_1 ?></option>
               <option value="<?= APP_LETTER_2 ?>"><?= APP_LETTER_2 ?></option>
               <option value="<?= REL_LETTER ?>"><?= REL_LETTER ?></option>
               <option value="<?= EXP_TER_LETTER ?>"><?= EXP_TER_LETTER ?></option>
            </select>
         </div>
      </div>
   </div>
   <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
      <!-- <button type="button" class="btn btn-primary btn-sm  waves-effect"><i class="material-icons">cloud_upload</i></button> -->
      <button type="button" class="btn btn-danger btn-sm  waves-effect remove-me"><i class="material-icons">delete_forever</i></button>
   </div>
</div>

这是动态生成输入标签的JS代码

$("#add-file-group").click(function() {
    // Dynamically generate the id for upload-group elements
    const count = $(".upload-area").find(".file-upload-group").length + 1;

    const newID = "upload-area-id-" + count;

    const fileUploadGroup = `<div class="row clearfix file-upload-group">
    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
        <div class="form-group">
            <div class="form-line">
                <input type="file" class="form-control" id="file_${count}" name="emp_doc_${count}">
            </div>
        </div>
    </div>
    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-6">
        <div class="form-group">
            <div class="form-line">
            <select name="emp_doc_type_${count}" id="emp_doc_type_${count}" data-size="2" class="form-control show-tick selectpicker" title="Choose one of the following..." tabindex="-98"><option class="bs-title-option" value="">Choose one of the following...</option>
                <option value="OFFER LETTER">OFFER LETTER</option>
                <option value="APPOINTEMENT LETTER">APPOINTEMENT LETTER</option>
                <option value="CONFIRMATION LETTER">CONFIRMATION LETTER</option>
                <option value="APPRAISAL LETTER 1">APPRAISAL LETTER 1</option>
                <option value="APPRAISAL LETTER 2">APPRAISAL LETTER 2</option>
                <option value="RELIVING LETTER">RELIVING LETTER</option>
                <option value="EXPERIENCE / TERMINATION LETTER">EXPERIENCE / TERMINATION LETTER</option>
            </select>
            </div>
        </div>
    </div>
    <div class="col-lg-4 col-md-4 col-sm-4 col-xs-12">
        <button type="button" class="btn btn-primary btn-sm  waves-effect"><i class="material-icons">cloud_upload</i></button>
        <button type="button" class="btn btn-danger btn-sm  waves-effect remove-me"><i class="material-icons">delete_forever</i></button>
        
    </div>
</div>`;

    $(".upload-area").append(fileUploadGroup);

    // Increment the doc counter of hidden field
    $('#emp_docs_count').val(count);

    // Refresh the selectpicker to work on this generated element
    $(".selectpicker").selectpicker("refresh");
});
                                    

确保您的表单输入的属性 enctypemultipart/form-data 并且您作为文件的输入具有名称 name[](创建所选中的每个文件都在数组中)并具有属性 multiple.

终于解决了,每次调用upload_file()方法只需要初始化上传库,加一行就可以了,

public function upload_file($dir, $input, $allowed_types = 'jpeg|jpg|png')
    {
        $config['upload_path']   = $dir;
        $config['allowed_types'] = !empty($allowed_types) ? $allowed_types : 'jpeg|jpg|png';
        $config['max_size']      = 0;
        $config['max_width']     = 0;
        $config['max_height']    = 0;
        $config['file_name']     = md5(time() . rand(1, 1000));

        $this->load->library('upload');

        $this->upload->initialize($config); //<-- this line solved it

        if (!$this->upload->do_upload($input)) {
            return array('error' => $this->upload->display_errors());
        } else {
            $data = $this->upload->data();

            // If it is image then resize it to reduce the image file size
            if ($data['is_image']) {
                $this->resize_image($data['full_path']);
            }

            return $data;
        }
    }