Ver Mensaje Individual
  #2 (permalink)  
Antiguo 21/08/2014, 23:33
Avatar de Alexis88
Alexis88
Philosopher
 
Fecha de Ingreso: noviembre-2011
Ubicación: Tacna, Perú
Mensajes: 5.552
Antigüedad: 13 años, 1 mes
Puntos: 977
Respuesta: Imagen repetida al subir a servidor, upload fotos

Noto inconsistencia en tu código, por ejemplo, el subíndice 'tmp_name' no es un array como para que lo intentes recorrer con un bucle, además, iteras cinco veces en el bucle cuando quizá no siempre se vayan a seleccionar cinco archivos.

Yo lo haría así:

Código HTML:
Ver original
  1. <form action = "upload.php" method = "post" enctype = "multipart/form-data">
  2.     Selecciona las imágenes: <input type = "file" name = "myFiles[]" multiple accept = "image/jpeg, image/png, image/gif" />
  3.     <input type = "submit" />
  4. </form>

Código PHP:
Ver original
  1. $files = $_FILES['myFiles'];
  2. $total = count($files['name']);
  3. $max_file_uploads = ini_get('max_file_uploads');
  4. $post_max_size = (int)ini_get('post_max_size');
  5. $upload_max_filesize = (int)ini_get('upload_max_filesize');
  6. $totalUploaded = 0;
  7. $types = array('image/jpeg', 'image/png', 'image/gif');
  8.  
  9. if ($total){
  10.     foreach ($files['size'] as $size) $totalUploaded += $size;
  11.     $totalUploaded /= 1048576;
  12.  
  13.     if ($total <= $max_file_uploads && $totalUploaded <= $post_max_size){
  14.         for ($i = 0; $i < $total; $i++){
  15.             $error = $files['error'][$i];
  16.             $size = $files['size'][$i] / 1048576;
  17.             $tmp_name = $files['tmp_name'][$i];
  18.             $name = $files['name'][$i];
  19.             $type = getimagesize($tmp_name)['mime'];
  20.  
  21.             if ($error == UPLOAD_ERR_OK && $size <= $upload_max_filesize && in_array($type, $types)){
  22.                 if (move_uploaded_file($tmp_name, 'img/' . $name)){
  23.                     echo 'El archivo ' . $name . ' ha sido subido<br />';
  24.                 }
  25.                 else{
  26.                     echo 'No se pudo subir el archivo ' . $name . '<br />';
  27.                 }
  28.             }
  29.             else{
  30.                 echo 'No se pudo subir el archivo ' . $name . ', su tamaño excede el límite o no es un archivo de imagen<br />';
  31.             }
  32.         }
  33.     }
  34.     else{
  35.         echo 'La cantidad de archivos seleccionados supera al máximo permitido o el tamaño combinado de los archivos seleccionados supera al tamaño máximo permitido';
  36.     }
  37. }
  38. else{
  39.     echo 'No has seleccionado archivos';
  40. }

Lo que hago es lo siguiente. Primero, en el formulario, tengo un <input> de tipo file, con nombre myFiles[] con corchetes para tratarlo como un array y en el archivo PHP, tomar los archivos seleccionados utilizando una estructura repetitiva y además, los atributos multiple para poder tomar a más de un archivo y accept con el que defino los tipos de archivo que el usuario podrá seleccionar, aunque puede cambiarse esto manualmente. Luego, en el archivo PHP, defino a las siguientes variables:
  • $files: Le asigno el array de archivos.
  • $total: El total de archivos subidos.
  • $max_file_uploads: La cantidad máxima de archivos que se permite subir al servidor.
  • $post_max_size: El tamaño combinado máximo de bytes que se permite subir al servidor.
  • $upload_max_filesize: El tamaño máximo de bytes por archivo que se permite subir al servidor.
  • $totalUploaded: Variable que originalmente tiene como valor 0 y que más adelante albergará la cantidad total de bytes sumados de todos los archivos seleccionados.
  • $types: Un array con los tipos de archivo permitidos.

Definido esto, verifico si se han seleccionado archivos, de ser así, procedo con las operaciones, caso contrario, muestro un mensaje indicándole al usuario que no ha seleccionado archivos. De darse el primer caso (que es el que obviamente esperamos), recorro la lista de valores con los tamaños de los archivos seleccionados y los voy acumulando en la variable $totalUploaded, cuyo valor final divido entre 1048576 (cantidad de bytes en un Megabyte) para obtener el equivalente en Megabytes. Luego, verifico que la cantidad de archivos seleccionados sea menor o igual al máximo permitido y que la cantidad total de Megabytes subidos entre todos los archivos seleccionados sea menor o igual a lo que permite el servidor, de cumplirse esto, procedo a recorrer al conjunto de archivos seleccionados utilizando para ello un bucle for y al inicio de cada iteración, defino a las siguientes variables:
  • $error: El código de error generado al seleccionar y subir temporalmente el archivo. La lista de códigos y su significado la puedes ver en el enlace que adjunto.
  • $size: El tamaño del archivo actual en la iteración, al cual divido entre 1048576 para obtener el equivalente en Megabytes.
  • $tmp_name: El nombre temporal del archivo actual en la iteración.
  • $name: El nombre del archivo actual en la iteración.
  • $type: El tipo real del archivo, esto es para evitar que el usuario intente subir un archivo disfrazado el cual podría ser de contenido malicioso. La función getimagesize me permite obtener dicho dato, pero también existen otras funciones.

Definido esto, verificamos que no haya ocurrido algún error al momento de subir temporalmente el actual archivo, que su tamaño sea menor o igual al máximo permitido por archivo y que el tipo del archivo actual se encuentre en el array con los tipos de archivo que definimos al inicio. De cumplirse todo esto, procedemos a subir el archivo, caso contrario, mostramos un mensaje indicándole al usuario que no se pudo subir el archivo por las razones que puedes ver en esa línea de código. Pero si todo se encuentra en orden, procedemos a subir el archivo; de realizarse la misma, mostramos un mensaje indicándole al usuario que el archivo actual en la iteración del bucle ha sido subido al servidor, caso contrario, mostramos un mensaje indicándole al usuario que no se pudo subir el archivo en cuestión.

Y eso es todo. Te sugiero que analices el código línea a línea por si te quedan duda o deseas realizar mejoras.

Saludos
__________________
«Juro por mi vida y mi amor por ella, que jamás viviré para el provecho de otro hombre, ni le pediré a otro hombre que viva para el mío».

Ayn Rand

Última edición por Alexis88; 22/08/2014 a las 10:56 Razón: Corrección en la indentación