1

Overview

I have a multi-part form that has four file upload fields and three of these are dynamically added (using JavaScript).

<input type="file" name="OneCertificate" />

<input type="file" id="MultipleCertificate[1] "name="MultipleCertificate[]" />
<input type="file" id="MultipleCertificate[2] "name="MultipleCertificate[]" />
// more if Add button is pressed 

Here is the output of var_dump($_FILES):

["OneCertificate"]=> array(5) {
        ["name"]=> string(6) "DE.pdf"
        ["type"]=> string(15) "application/pdf"
        ["tmp_name"]=> string(24) "C:\xampp\tmp\php37C2.tmp"
        ["error"]=> int(0)
        ["size"]=> int(103845)
}
// **Notice the attributes are all in their own arrays**
["MultipleCertificate"]=> array(5) { 
    ["name"]=> array(2) { [0]=> string(6) "DE.pdf" [1]=> string(6) "DE.pdf" } 
    ["type"]=> array(2) { [0]=> string(15) "application/pdf" [1]=> string(15) "application/pdf" } 
    ["tmp_name"]=> array(2) { [0]=> string(24) "C:\xampp\tmp\phpD941.tmp" [1]=> string(24) "C:\xampp\tmp\phpD942.tmp" } 
    ["error"]=> array(2) { [0]=> int(0) [1]=> int(0) } 
    ["size"]=> array(2) { [0]=> int(103845) [1]=> int(103845) } 
 }
 // and so on...

Below is how I upload each file:

function upload_file($field_name)
{
    // timestamp name: http://stackoverflow.com/questions/7457152/did-not-select-a-file-to-upload-when-uploading-using-codeigniter
    $the_date= date('Y/n/j h:i:s');
    $replace = array(":"," ","/");
    $new_name = str_ireplace($replace, "-", $the_date);

    $config['upload_path'] = './uploads/';
    $config['file_name'] = $new_name;
    $config['allowed_types'] = 'pdf|jpg|jpeg|png';

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

    // Get OneCertificate the normal way since it will only have one file content
    if ( $field_name == 'OneCertificate' ) {
        if ( ! $this->upload->do_upload($field_name)) {
            return array('error' => $this->upload->display_errors());
        } else {
            $file_data = array('upload_data' => $this->upload->data());
        }
    // Method for MultipleCertificate
    } else {
        for ($i = 0; $i < count($_FILES[$field_name]['name']); $i++) {
            if ( ! $this->upload->do_upload($_FILES[$field_name]['name'][$i])) {
                $file_data = array('error' => $this->upload->display_errors());
            } else {
                $file_data = array('upload_data' => $this->upload->data());
            }
         } // END for loop  
    }

    return $file_data;
 }

The Problem

I noticed that the format of OneCertificate works since all of its information are in a single array compared to MultipleCertificate that has each attribute in its own array.

The first manages to successfully upload a file but the latter throws a You did not select a file to upload.

How do I transform and/or retrieve the form of MultipleCertificate into OneCertificate?

Note: This is the form I need since I will assign the arrays created to $OneCertificate and $MultipleCertificate for database insertion.

  • you call function `do_upload` in 1st case with parameter `"OneSertificate"`, not with file name, and in second case with file name as a parameter. What does function `do_upload()` accept as parameters and what does it do with parameters? – user15 Feb 17 '13 at 11:51
  • @user15 - `do_upload()` takes the name of `input[type=file]` –  Feb 17 '13 at 11:53
  • 1
    http://stackoverflow.com/a/1908577/427992 – hohner Feb 17 '13 at 11:59

1 Answers1

0

For anyone who had a problem like mine regarding how $_FILES handles file arrays, hohner's comment above solved the problem.

Here is the SO link to the answer.

Basically my "looping to the inner arrays of the $_FILE array" goes like this:

function do_upload($file_name)
{
    $this->load->library('upload');
    $this->total_count_of_files = count($_FILES[$file_name]['name']);

    // timestamp name: https://stackoverflow.com/questions/7457152/did-not-select-a-file-to-upload-when-uploading-using-codeigniter
    $date_timestamp = date('Y/M/j h:i:s');
    $replace = array(":"," ","/");
    $new_name = $file_name.'-'.$this->session->userdata('AccreditNo').'-'.str_ireplace($replace, '', $date_timestamp);

    for($i = 0; $i < $this->total_count_of_files; $i++) {
        // userfile is arbitrary, it will not reflect on the final array
        $_FILES['userfile']['name']     = $_FILES[$file_name]['name'][$i];
        $_FILES['userfile']['type']     = $_FILES[$file_name]['type'][$i];
        $_FILES['userfile']['tmp_name'] = $_FILES[$file_name]['tmp_name'][$i];
        $_FILES['userfile']['error']    = $_FILES[$file_name]['error'][$i];
        $_FILES['userfile']['size']     = $_FILES[$file_name]['size'][$i];

        $config['file_name']     = $new_name.'-'.$i;
        $config['upload_path']   = "./uploads/$file_name";
        $config['allowed_types'] = 'pdf|jpg|jpeg|png';
        $config['max_size']      = '0';

        $this->upload->initialize($config);

        if ( ! $this->upload->do_upload()) {
            $file_data = array('error' => $this->upload->display_errors());
        } else {
            $file_data = array("file_{$i}" => $this->upload->data());
        }
    }

    return $file_data;
}   

File data will now contain the assembled attributes of one file to be inserted to the database! (how I want it to be in this case)

Community
  • 1
  • 1