Codeigniter multiple file upload messes file extension

34,112

Solution 1

I solved this exact problem by amending the Upload.php files located in the library folder.

Comment out line 935:

$filename = $this->file_name;

Solution 2

Faced the exact similar stuff 2 days ago but did it the old fashioned way hope it helps. try this ..

function tester(){

 $this->load->library('upload');  // NOTE: always load the library outside the loop
 $this->total_count_of_files = count($_FILES['filename']['name'])
 /*Because here we are adding the "$_FILES['userfile']['name']" which increases the count, and for next loop it raises an exception, And also If we have different types of fileuploads */
 for($i=0; $i<$this->total_count_of_files; $i++)
 {

   $_FILES['userfile']['name']    = $_FILES['filename']['name'][$i];
   $_FILES['userfile']['type']    = $_FILES['filename']['type'][$i];
   $_FILES['userfile']['tmp_name'] = $_FILES['filename']['tmp_name'][$i];
   $_FILES['userfile']['error']       = $_FILES['filename']['error'][$i];
   $_FILES['userfile']['size']    = $_FILES['filename']['size'][$i];

   $config['file_name']     = 'test_'.$i;
   $config['upload_path']   = './public/uploads/';
   $config['allowed_types'] = 'jpg|jpeg|gif|png';
   $config['max_size']      = '0';
   $config['overwrite']     = FALSE;

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

  if($this->upload->do_upload())
  {
    $error += 0;
  }else{
    $error += 1;
  }
 }

 if($error > 0){ return FALSE; }else{ return TRUE; }

}

Solution 3

For me it was enough to recall $this->upload->initialize($config); every time I called $this->upload->do_upload()

Solution 4

I am a bit confused by your answer thephpx. Won't restructuring $_FILES like that kill off the subarrays once you ahve run it once?

At any rate, I was trying OP's approach by adding the extra index to the a few of the upload library's lines.

I made it work by putting the for loop (over all files) in the upload controller, and the extra index $k as a parameter in the do_upload function in the library.

            $this->load->library('upload');
        for ($k = 0; $k < count($_FILES['userfile']['name']); $k++) {
            $this->upload->initialize($upload); //must reinitialize to get rid of your bug ( i had it as well)
            if (!$this->upload->do_upload('userfile',$k)) {
                $this->load->view('upload/image_form', $data + array('error'=>$this->upload->display_errors()));
            }
            $udata[$k] = $this->upload->data(); //gradually build up upload->data()
        }
Share:
34,112
Udders
Author by

Udders

Updated on July 09, 2022

Comments

  • Udders
    Udders almost 2 years

    I am trying to get a multiple upload library working for my Codeigniter based website. I have it working almost but I have a slight problem if I upload more than one image, the file extentions get screwed up; for example, if I upload three JPEGS, I get this in my uploads folder,

    image1.jpg
    image2.jpg.jpg
    image3.jpg.jpg.jpg
    

    I cannot see what is causing it, this is the library in question and I am pretty sure that it is in there that the problem is,

    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); 
    
    /**
    * This library assumes that you have already loaded the default CI Upload Library seperately
    * 
    * Functions is based upon CI_Upload, Feel free to modify this 
    *   library to function as an extension to CI_Upload
    * 
    * Library modified by: Alvin Mites
    * http://www.mitesdesign.com
    * 
    */
    
    class Multi_upload  {
        function Multi_upload () {
    //      $CI =& get_instance();
        }
    
        /**
         * Perform multiple file uploads
         * Based upon JQuery Multiple Upload Class
         * see http://www.fyneworks.com/jquery/multiple-file-upload/
         */ 
        function go_upload($field = 'userfile') {
            $CI =& get_instance(); 
            // Is $_FILES[$field] set? If not, no reason to continue.
            if ( ! isset($_FILES[$field]['name'][0]))
            {
                $CI->upload->set_error('upload_no_file_selected');
                return FALSE;
            } else
            {
                $num_files = count($_FILES[$field]['name']) -1;
                $file_list = array();
                $error_hold = array();
                $error_upload = FALSE;
            }
    
            // Is the upload path valid?
            if ( ! $CI->upload->validate_upload_path())
            {
                // errors will already be set by validate_upload_path() so just return FALSE
                return FALSE;
            }
    
            for ($i=0; $i < $num_files; $i++) {
    
    //          $fname = $_FILES[$field]['name'][$i];
    //          echo "$fname\n\n<br><br>\n\n";
    
                $error_hold[$i] = FALSE;
    
                // Was the file able to be uploaded? If not, determine the reason why.
                if ( ! is_uploaded_file($_FILES[$field]['tmp_name'][$i]))
                {
                    $error = ( ! isset($_FILES[$field]['error'][$i])) ? 4 : $_FILES[$field]['error'][$i];
    
                    switch($error)
                    {
                        case 1:  // UPLOAD_ERR_INI_SIZE
                            $error_hold[$i] = 'upload_file_exceeds_limit';
                            break;
                        case 2: // UPLOAD_ERR_FORM_SIZE
                            $error_hold[$i] = 'upload_file_exceeds_form_limit';
                            break;
                        case 3: // UPLOAD_ERR_PARTIAL
                           $error_hold[$i] = 'upload_file_partial';
                            break;
                        case 4: // UPLOAD_ERR_NO_FILE
                           $error_hold[$i] = 'upload_no_file_selected';
                            break;
                        case 6: // UPLOAD_ERR_NO_TMP_DIR
                            $error_hold[$i] = 'upload_no_temp_directory';
                            break;
                        case 7: // UPLOAD_ERR_CANT_WRITE
                            $error_hold[$i] = 'upload_unable_to_write_file';
                            break;
                        case 8: // UPLOAD_ERR_EXTENSION
                            $error_hold[$i] = 'upload_stopped_by_extension';
                            break;
                        default :
                            $error_hold[$i] = 'upload_no_file_selected';
                            break;
                    }
    
                    return FALSE;
                }
    
                // Set the uploaded data as class variables
                $CI->upload->file_temp = $_FILES[$field]['tmp_name'][$i];        
                $CI->upload->file_name = $CI->upload->_prep_filename($_FILES[$field]['name'][$i]);
                $CI->upload->file_size = $_FILES[$field]['size'][$i];        
                $CI->upload->file_type = preg_replace("/^(.+?);.*$/", "\\1", $_FILES[$field]['type'][$i]);
                $CI->upload->file_type = strtolower($CI->upload->file_type);
                $CI->upload->file_ext  = $CI->upload->get_extension($_FILES[$field]['name'][$i]);
    
                // Convert the file size to kilobytes
                if ($CI->upload->file_size > 0)
                {
                    $CI->upload->file_size = round($CI->upload->file_size/1024, 2);
                }
    
                // Is the file type allowed to be uploaded?
                if ( ! $CI->upload->is_allowed_filetype())
                {
                    $error_hold[$i] = 'upload_invalid_filetype';
                }
    
                // Is the file size within the allowed maximum?
                if ( ! $CI->upload->is_allowed_filesize())
                {
                    $error_hold[$i] = 'upload_invalid_filesize';
                }
    
                // Are the image dimensions within the allowed size?
                // Note: This can fail if the server has an open_basdir restriction.
                if ( ! $CI->upload->is_allowed_dimensions())
                {
                    $error_hold[$i] = 'upload_invalid_dimensions';
                }
    
                // Sanitize the file name for security
                $CI->upload->file_name = $CI->upload->clean_file_name($CI->upload->file_name);
    
                // Remove white spaces in the name
                if ($CI->upload->remove_spaces == TRUE)
                {
                    $CI->upload->file_name = preg_replace("/\s+/", "_", $CI->upload->file_name);
                }
    
                /*
                 * Validate the file name
                 * This function appends an number onto the end of
                 * the file if one with the same name already exists.
                 * If it returns false there was a problem.
                 */
                $CI->upload->orig_name = $CI->upload->file_name;
    
                if ($CI->upload->overwrite == FALSE)
                {
                    $CI->upload->file_name = $CI->upload->set_filename($CI->upload->upload_path, $CI->upload->file_name);
    
                    if ($CI->upload->file_name === FALSE)
                    {
                        $error_hold[$i] = TRUE;
                    }
                }
    
                /*
                 * Move the file to the final destination
                 * To deal with different server configurations
                 * we'll attempt to use copy() first.  If that fails
                 * we'll use move_uploaded_file().  One of the two should
                 * reliably work in most environments
                 */
                if ( ! @copy($CI->upload->file_temp, $CI->upload->upload_path.$CI->upload->file_name))
                {
                    if ( ! @move_uploaded_file($CI->upload->file_temp, $CI->upload->upload_path.$CI->upload->file_name))
                    {
                         $error_hold[$i] = 'upload_destination_error';
                    }
                }
    
                /*
                 * Run the file through the XSS hacking filter
                 * This helps prevent malicious code from being
                 * embedded within a file.  Scripts can easily
                 * be disguised as images or other file types.
                 */
                if ($CI->upload->xss_clean == TRUE)
                {
                    $CI->upload->do_xss_clean();
                }
    
                if ($error_hold[$i]) {
                    $error_upload = TRUE;
    
    //                echo $error_hold[$i];
                } else {
                    if ($imageVar = $this->multiple_image_properties($CI->upload->upload_path.$CI->upload->file_name)) {
    
                        $file_list[] = array(
                                'name' => $CI->upload->file_name,
                                'file' => $CI->upload->upload_path.$CI->upload->file_name,
                                'size' => $CI->upload->file_size,
                                'ext' => $CI->upload->file_ext,
                                'image_type' => $imageVar->image_type,
                                'height' => $imageVar->height,
                                'width' => $imageVar->width
                                );
                    } else {
                        $file_list[] = array(
                                'name' => $CI->upload->file_name,
                                'file' => $CI->upload->upload_path.$CI->upload->file_name,
                                'size' => $CI->upload->file_size,
                                'type' => $CI->upload->file_type,
                                'ext' => $CI->upload->file_ext,
                                );
                    }
                }
    
    // For debugging
    /*            
                if (strlen($error_hold[$i]) > 1) {
                        print_r($error_hold);
                }
    */            
            } // end for loop
    
            // Add error display for individual files        
            if ($error_upload) {
                $this->set_error($error_hold);
                return FALSE;
            } else {
                return $file_list;
            }    
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Set Image Properties
         *
         * Uses GD to determine the width/height/type of image
         *
         * @access    public
         * @param    string
         * @return    void
         */    
        function multiple_image_properties($path = '')
        {
            $CI =& get_instance(); 
            if ( ! $CI->upload->is_image())
            {
                return false;
            }
    
            if (function_exists('getimagesize'))
            {
                if (FALSE !== ($D = @getimagesize($path)))
                {    
                    $types = array(1 => 'gif', 2 => 'jpeg', 3 => 'png');
    
                    $image->width       = $D['0'];
                    $image->height      = $D['1'];
                    $image->image_type        = ( ! isset($types[$D['2']])) ? 'unknown' : $types[$D['2']];
    
                    return $image;
                }
            }
        }
    
        // --------------------------------------------------------------------
    
        /**
         * Set an error message
         *
         * @access    public
         * @param    string
         * @return    void
         */    
        function set_error($msg)
        {
            $CI =& get_instance();    
            $CI->lang->load('upload');
    
            if (is_array($msg))
            {
                foreach ($msg as $val)
                {
                    $msg = ($CI->lang->line($val) == FALSE) ? $val : $CI->lang->line($val);                
                    $this->error_msg[] = $msg;
                    log_message('error', $msg);
                }        
            }
            else
            {
                $msg = ($CI->lang->line($msg) == FALSE) ? $msg : $CI->lang->line($msg);
                $this->error_msg[] = $msg;
                log_message('error', $msg);
            }
        }
    
        // --------------------------------------------------------------------
    }
    ?>
    
  • Nur Amsyari
    Nur Amsyari about 14 years
    this had been giving me a headache all morning, I modded your version for myself and it works great!
  • Nur Amsyari
    Nur Amsyari about 14 years
    "Won't restructuring $_FILES like that kill off the subarrays once you ahve run it once?" No. He is only modifying the $_FILES['userfile'] array (not his initial $_FILES['filename'] array. As the do_upload() is being run inside the loop, the $_FILES['userfile'] array being rest every time doesn't matter.
  • DonutReply
    DonutReply almost 14 years
    This worked for me. For some reason it was retaining the config data from the previous call to do_upload. Calling initialize() forces it to update the config data.
  • k00k
    k00k almost 14 years
    This is pretty good. There are some syntax errors, but with a bit of tweaking it works. replace foreach with for. replace $j with $i
  • Daniel West
    Daniel West about 12 years
    @JannieT It counts the number of error messages, then at the end if the number of errors are 0 then true is returned, otherwise false is returned.
  • Jannie Theunissen
    Jannie Theunissen about 12 years
    @Daniel ummm I was suggesting the code be simplified to if(!$this->upload->do_upload()) { $error += 1; } without the else
  • Daniel West
    Daniel West about 12 years
    @JannieT Yeah I see what you mean, depends on your coding style :)
  • Pjottur
    Pjottur almost 11 years
    This will cause problems when you upload a single file.
  • glihm
    glihm over 4 years
    The definitive solution. Thank you @Mihai MATEI.