2009-12-15 98 views
20

我想获得一个多上传库,为我的基于Codeigniter的网站工作。我有它几乎工作,但我有一个小问题,如果我上传多个图像,文件扩展被搞砸了;举例来说,如果我上传三张JPEGS,我得到这个在我的上传文件夹,Codeigniter多文件上传messes文件扩展名

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

我看不出是什么原因造成的,这是有问题的图书馆,我敢肯定,这是在那里的问题是,

<?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); 
     } 
    } 

    // -------------------------------------------------------------------- 
} 
?> 

回答

7

我通过修改位于库文件夹中的Upload.php文件解决了这个问题。

注释掉行935:

$filename = $this->file_name; 
17

面对2天前的确切类似的东西,但它做了老式的方式,希望它有所帮助。 试试这个..

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; } 

} 
+2

整个上午这让我头疼,我为自己修改了你的版本,它效果很棒! – 2010-02-24 12:19:33

+1

这很不错。有一些语法错误,但稍微调整它的作用。 将foreach替换为for。用$ i替换$ j – k00k 2010-07-26 23:18:31

+0

是的,有用的答案。只是不确定$ error + = 0是干什么的。 – 2010-07-27 04:54:23

1

我对你的答案thephpx有点困惑。一旦你运行一次,不会重组像$ _FILES那样的子程序吗?

无论如何,我试图通过在上传库的一些行中添加额外的索引来实现OP的方法。

我通过在上传控制器中放置for循环(通过所有文件),并将额外的索引$ k作为库中do_upload函数的参数来实现它。

  $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() 
     } 
+0

“不会重组$ _FILES就像这样杀掉了子阵列,一旦你运行一次吗?”他只修改$ _FILES ['userfile']数组(不是他最初的$ _FILES ['filename']数组。)当do_upload()在循环内部运行时,$ _FILES ['userfile']阵列每次休息都没关系 – 2010-02-24 12:21:17

3

对我来说,这已经足够我每次叫$this->upload->do_upload()

+0

这对我很有帮助,由于某种原因,它保留了前一次调用do_upload的配置数据,调用initialize()强制它更新配置数据 – DonutReply 2010-06-18 12:51:40

+0

工作感谢 – 2011-08-25 06:47:58

0

时间我能得到多文件上传与clux的方法,但我的工作回顾 $this->upload->initialize($config); 必须稍微修改上传类(我使用Codeigniter 2)。首先,我创建了CI上传类到我的应用程序库中的副本。

143线:

public function do_upload($field = 'userfile') 

变化

public function do_upload($field = 'userfile', $i = 0) 

和线条160和200之间,你必须添加[$ i]到$ _FILES变量的结束。

实施例:

is_uploaded_file($_FILES[$field]['tmp_name']) 

变化:

is_uploaded_file($_FILES[$field]['tmp_name'][$i]) 

相信有一个总的其中9是。

+0

这个当您上传单个文件时会导致问题。 – Pjottur 2013-07-08 19:11:19