En el ejemplo anterior, todos los valores del campo lectura[] se convierten en un array, en el servidor, al ser enviado por el formulario. Este array $_POST['lectura'] no se puede guardar en la tabla.
Como los array de PHP están en memoria RAM del servidor, no se pueden guardar como tal, pero sí lo podemos convertir en una cadena estructurada de datos. Para eso PHP tiene las funciones serialize() que permiten convertir un Array en una cadena estructurada de datos y unserialize() que permite volver a un Array la cadena estructurada.
Si vemos la estructura, es muy parecido al concepto de JSON (JavaScript Object Notation) para transmitir objetos y arrays como cadena de texto de manera estructurada.
Revisemos el resultado de esta función sobre el array. Dice que es un array de 6 elementos (a:6). En el primer campo (i:0) tiene una cadena de 3 caracteres (s:3) y su valor es uno. El segundo elemento (i:1) tiene un entero que vale 2 (i:2) el tercer elemento en la posicion 2 (i:2) tiene una cadena de 4 caracteres (s:4) que vale tres, etc.
Ahora que es una cadena, se puede guardar en una tabla para tener su persistencia.
unserialize()
La función unserialize() por el contrario, se encarga de tomar esta cadena que hemos guardado y volverla a un formato de array para PHP
Subir archivos desde el navegador al servidor no es tan complejo utilizando la función de PHP move_uploaded_file(), pero sí requiere revisar 3 elementos para que esto se pueda realizar y comprender el comportamiento de Apache con respecto a los archivos.
Vamos por pasos, lo primero es que el formulario que va a enviar el archivo tiene que sí o sí ser con el método POST, ya que no se puede adjuntar un archivo como parte de la URL, que es el caso del método GET.
El segundo elemento fundamental para que el formulario pueda enviar el archivo, es que el formulario deber tener el atributo enctype="multipart/form-data. Normalmente los formularios capturan y transmiten los datos como texto simple (text/plain) o como dato procesado sin espacio y convirtiendo los caracteres especiales en valores ASCapplication/x-www-form-urlencodedapplication/x-www-form-urlencoded HEX (application/x-www-form-urlencoded). Al transmitirlo encriptado como multipart/form-data lo que le dice que no encripte el contenido de los campos del tipo file para que no sufra alteraciones.
El segundo elemento que tenemos que tener claro es dónde sube el archivo Apache y cómo lo recupero para utilizarlo.
Tenemos que entender, que en la configuración del PHP, en el archivo php.ini, se define el directorio de destino cuando se suben los archivos. Estos suelen ser directorios temporales, o sea que el sistema está borrando su contenido periódicamente para que no sobresature la capacidad de la máquina.
Si le pedimos al PHP que nos muestre el valor que está recibiendo en la variable global $_FILES[], nos damos cuenta que tiene varios valores para el archivo que estamos subiendo:
Si revisamos lo que recibió el archivo php de destino upload.php, veremos un array para el campo de formulario archivo con el nombre del archivo, el tipo de archivo, el nombre temporal del archivo, si hubo o no errores, y cuánto pesa el archivo recibido.
El tercero, el nombre temporal tmp_name tiene la ruta y nombre que le asignó Apache al subir el archivo. Ahora, lo que debemos hacer es tomar de ese lugar el archivo y moverlo a su destino final controlable en el directorio de nuestra aplicación con la función move_uploaded_file().
En este caso, si recibimos de respuesta "archivo arriba", entonces podemos revisar el directorio upload, que definimos como destino, y debería estar el archivo que subimos con el mismo nombre.
Nota:
Uno de los errores clásicos, por el que no funciona el subir archivo, es que el directorio de destino no tiene permisos para escribir. (chmod 777). Hay que recordar que las acciones de Apache son generadas como anónimo, por lo que el permiso de escritura y ejecución tiene que ser al menos 6 para el anónimo.
El resto del tratamiento de los archivos subidos va a depender de los requerimientos del diseño. Si necesitamos registrar en una BD los datos del archivo, o tener mayor control sobre el nombre que se le asigna o validar que tenga un formato específico o menor a un peso máximo, son intervenciones sobre este mismo código.
Ejemplo:
<?php
if ( isset( $_POST[ 'enviar' ] ) && $_POST[ 'enviar' ] == "enviar" ) {
$file_type = $_FILES[ 'archivo' ][ 'type' ]; //devuelve el mimetype o tipo de archivo
$permitidos = array( "image/jpeg", "image/gif", "image/png" );//lista de archivos permitidos
if ( !in_array( $file_type, $permitidos ) ) {//si el tipo de archivoestá en la lista permitida.
$error_message = 'Sólo se permiten archivos jpg, gif, y png.';
echo $error_message;//devuelve mensaje de error.
exit();//termina el proceso
} else if ( ( $_FILES[ "archivo" ][ "size" ] > 2000000 ) ) {// si el tamaño del archivo es mayor a 2megas
$error_message = 'El tamaño del archivo no puede ser de más de 2MB.';
echo $error_message;//devuelve mensaje de error.
exit();//termina el proceso
} else {
$extension = pathinfo( $_FILES[ "archivo" ][ "name" ], PATHINFO_EXTENSION );//extráe la extensión del archivo de su nombre original
$nombre_nuevo = date( 'YmdHis' ) . "." . $extension;//construye nuevo nombre para el archivo
$origen = $_FILES[ 'archivo' ][ 'tmp_name' ];
$destino = "upload/" . $nombre_nuevo;//define nombre y destino del archivo
if ( move_uploaded_file( $origen, $destino ) ) {
echo "archivo arriba";
} else {
echo "ups, hubo un error al mover el archivo";
}
}
}
?>
En el ejemplo anterior, primero valida que sea un formato de imagen, que no pese más de 2MB y le cambia el nombre a un archivo a un dato único e irrepetible compuesto por el "timestamp" de la fecha/hora en que se procesa.
Ejercicio:
Generar un administrador de archivos a subir. Página maestra que se alimente de una BD con todos los archivos subidos y vínculo para ver o descargar el archivo listado. Debe tener un formulario para subir nuevos archivos.