2009-12-15 97 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