2009-12-15 12 views
20

Estoy tratando de obtener una biblioteca de carga múltiple que funcione para mi sitio web basado en Codeigniter. Lo tengo casi funcionando pero tengo un pequeño problema si cargo más de una imagen, las extensiones de archivo se estropean; por ejemplo, si subo tres archivos JPEG, me sale esto en mi carpeta de archivos,Codeigniter carga de archivos múltiples messes extensión de archivo

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

no puedo ver lo que está causando, esta es la biblioteca en cuestión y estoy bastante seguro de que es ahí que la el problema es,

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

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

Respuesta

7

Resolví este problema exacto al enmendar los archivos Upload.php ubicados en la carpeta de la biblioteca.

como comentario la línea 935:

$filename = $this->file_name; 
17

Enfrentado exactamente lo mismo hace 2 días, pero lo hizo a la manera antigua espero que ayude. probar este ..

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

esto me ha estado dando un dolor de cabeza toda la mañana, modifiqué tu versión para mí y funciona muy bien! –

+1

Esto es bastante bueno. Hay algunos errores de sintaxis, pero con un poco de ajuste funciona. reemplazar foreach por. reemplace $ j con $ i – k00k

+0

Sí, respuesta útil. Simplemente no estoy seguro de qué $ error + = 0 hace. –

1

estoy un poco confundido por su thephpx respuesta. ¿No reestructurará $ _FILES así matando los subarreglos una vez que lo hayas ejecutado una vez?

En cualquier caso, estaba intentando el enfoque de OP agregando el índice extra a algunas de las líneas de la biblioteca de carga.

Lo hice funcionar colocando el bucle for (sobre todos los archivos) en el controlador de carga, y el índice adicional $ k como un parámetro en la función do_upload en la biblioteca.

  $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

"¿No reestructurará $ _FILES así matar a los subarreglos una vez que lo hayas ejecutado una vez?" No. Solo está modificando la matriz $ _FILES ['userfile'] (no su matriz inicial $ _FILES ['filename']. Como do_upload() se está ejecutando dentro del bucle, $ _FILES ['userfile'] el arreglo de estar en reposo todo el tiempo no importa. –

3

Para mí fue suficiente para recordar $this->upload->initialize($config); cada vez que se llama $this->upload->do_upload()

+0

Esto funcionó para mí. Por alguna razón, conservaba los datos de configuración de la llamada anterior a do_upload. Llamar a initialize() lo obliga a actualizar los datos de configuración. – DonutReply

+0

Funcionó –

0

yo era capaz de conseguir múltiples cargas de archivos para trabajar con el método de CLUX pero tuve que modificar la clase de carga ligeramente (estoy usando Codeigniter 2). Primero creé un duplicado de la clase de carga de CI en mi biblioteca de aplicaciones.

Línea 143:

public function do_upload($field = 'userfile') 

cambio a

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

Y entre las líneas 160 y 200, debe agregar [$ i] a finales de los $ _FILES variables.

Ejemplo:

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

cambio a:

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

Creo que hay un total de 9 de ellos.

+0

Esto causará problemas al cargar un solo archivo. – Pjottur

Cuestiones relacionadas