Plantilla:PHP/Formularios/transmisionFicheros

Transfiriendo ficheros entre cliente y servidor
Imagen:subirFicheros.png
 * Es muy sencillo y frecuente subir ficheros entre cliente y servidor
 * Cuando vamos a subir ficheros hay que conocer acciones a indicar tanto en la parte de cliente como en la de servidor.

Acciones en el Cliente

 * input type=file
 * Debemos especificar un elemento input con de type file en un formulario.
 * Como todo input debe tener asignado un name para acceder a él en el servidor.
 * form method=POST enctype="multipart/form-data
 * El formulario donde esté el input ha de tener especificado el atributo enctype establecido con el valor mutipart/form-data.
 * Cuando no especificamos valor a este atributo, se asume por defecto el valor application/x-www-form-urlencoded.
 * Este valor implica que enviamos texto plano y lo podremos enviar tanto por GET como por POST.
 * No obstante si vamos a transferir un fichero no necesariamente de texto debemos especificarlo estableciendo el valor de enctype a mutipart/form-data.
 * Este valor se emplea para transferir gran cantidad de texto u otros formatos de fichero entre cliente y servidor.

enctype es un atributo necesario para especificar el tipo de contenio usado para enviar la información del formulario al servidor.
 * Necesariamente hemos de usar el método POST para este cometido.
 * Establecer tamaño en el cliente
 * El tamaño de bytes que vamos a enviar también puede quedar establecido en el cliente, de modo que si el fichero tiene un tamaña mayor, no se envía.
 * Para esto se establece antes del input file, un input hidden con name a MAX_SIZE_FILE y value el valor del tamaño máximo en bytes.
 * Este mecanismo no envía nada al servidor, dejará de enviar el fichero al servidor.
 * En el servidor se recibirá un error de valor 2 o constante UPLOAD_ERR_FORM_SIZE, (Ver código de errores más abajo o en http://php.net/manual/es/features.file-upload.errors.php 
 * Con todo lo dicho, la especificación en el cliente quedaría

Acciones en el Servidor: $_FILES

 * La forma de acceder al input del tipo file que viene del cliente en la solicitud al servidor es a través de la superglobal $_FILES.
 * Lo primero que deberemos hacer es acceder a este elemento con el nombre del input.
 * $_FILES es un array asociativo con tantos elementos con input de tipo file como vengan del formulario cuyo submit ha generado una solicitud al servidor.
 * Cada posición a su vez contiene un array asociativo con información de ese fichero almacenada en 5 componentes:
 * 1) name Nombre del fichero en el cliente
 * 2) type Tupo de fichero subido
 * 3) size Tamaño en bytes del fichero
 * 4) tpm_name Nombre asignado de forma temporal en el servidor
 * 5) error Error que se haya podido producir o 0 si no ha habido ninguno (Ver tabla más abajo)

Con el fichero que viene del cliente, en el servidor podemos hacer una serie de acciones:
 * 1) Capturar el fichero y dejarlo en un directorio concreto.
 * 2) Ver si se ha producido algún error especificando el código de error mediante una constante numérica.
 * 3) Ver el tamaño del fichero.
 * 4) Analizar el tipo de fichero para poder, por ejemplo, aceptarlo o descartarlo, o decidir en qué carpeta dejarlo en función del tipo. (Tener en cuenta que haya permisos de escritura para el usuario de apache (www-data) en la carpeta donde queramos dejar el fichero)

Copiando el fichero a una carpeta

 * La primera acción será copiarnos el fichero en una ubicación concreta dentro de nuestro servidor
 * Lógicamente primero deberemos crear esa carpeta y asegurarnos que tenga permisos de escritura en ella el usuario apache (normalmente www-data)


 * En el servidor tenemos el fichero disponible de forma temporal en la capeta /tmp. Podemos acceder a esta información en el elemento $_FILES['tmp_name']
 * Para copiarlo usaremos la función move_uploaded_file($origen, $destino);, dónde $origen es el fichero que queremos copiar con ubicación y $destino es la ubicación y nombre de fichero donde queremos dejarlo.
 * Lo más habitual es dejar el fichero con el mismo nombre que tenía en el cliente, esta información la tenemos disponible en el atributo $_FILES['name']
 * La función ''move_upload(..) retorna un booleano que indica el éxito o fracaso de la acción. http://php.net/manual/es/function.move-uploaded-file.php.
 * A continuación un resumen de estas acciones

Comprobando errores
Imagen:inputFilePhp.png
 * $_FILES[error] contiene información del error que se ha podido producir al subir el fichero
 * La siguiente tabla es la lista de los posibles valores que va a haber en este elemento del array superglobal $_FILES


 * Un posible código para obtener esta información

Ver tamaño del fichero y otras directivas en php.ini
upload_max_filesize=
 * El tamaño de fichero queda definido en el servidor por la directiva de ''php.ini'
 * Otras directivas relacionadas con la descargas de ficheros están establecidas en php.ini
 * A continuación se detallan con sus valores por defecto. (Ver el fichero php.ini)


 * Podemos ver el tamaño exacto del fichero subido mediante el elemento size del array
 * Entre otras cosas puede servir para descartar un fichero de menos de un tamaño concreto.

Tipo de fichero

 * Este es un atributo importante

.....
 * 1) Analizar el tipo de fichero para poder por ejemplo aceptarlo o descartarlo o decidir en qué carpeta dejarlo en función del tipo
 * Para ver el tipo podemos observar la extensión del fichero.
 * O bien analizar el tipo MIME que nos viene en '$_FILES['type']
 * Por ejemplo suponemos que queremos distribuir los ficheros en tres carpetas
 * 1) Los ficheros que contengan imágenes a la carpeta ./descargas/imagenes/
 * 2) Los ficheros que contengan música a la carpeta ./descargas/musica/
 * 3) El resto de ficheros a la carpeta ./descargas/otros/
 * En el tipo mime separa el tipo general del fichero con una barra.
 * Así los de tipo música o audio sería 'audio/....'
 * Así los de tipo imagen 'image/....'


 * Un posible código sería