Cómo guardar archivos en MySQL desde php
|Guardar archivos dentro de una base de datos debe ser una decisión muy bien analizada si es conveniente porque según el tamaño de las mismas pueden inflar enormemente la base de datos pudiendo hacerla un poco más lenta al momento de hacer peticiones a dicha tabla, porsupuesto debemos tomar en cuenta cuantos registros irás a tener.
Solo decir un ejemplo imaginemos que tenemos una tabla con 1000 registros de solo texto a un promedio de 0.2 kb por registro esto es igual a 200 kb en total. Por otro lado si registramos archivos, digamos imágenes, un promedio de 64 kb cada una por 1000 registros estamos hablando de 62.5 mb, es decir que ha crecido 320 veces con respecto a la primera.
En lo personal prefiero guardar la imagen en el servidor web y la ruta a la imagen en la base de datos, pero si el cliente te dice que así lo quiere por más que lo querras disuadir pues ni modo, es por eso que te dejo este código para realizar dicha tarea.
Este código trabaja de manera general para todo tipo de archivos como por ejemplo imagenes o arhivos pdf.
1 2 3 4 5 6 7 |
DROP TABLE IF EXISTS `archivos`; CREATE TABLE IF NOT EXISTS `archivos` ( `id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT, `nombre` varchar(200) NOT NULL, `tipo` varchar(200) NOT NULL, `archivo` longblob NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
El tipo de datos donde vamos a guardar el archivo es longblob.
Este es el código que podemos usar para guardar el archivo en MySQL:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
<?php //verifica si se ha hecho clic en el boton guardar if(filter_input(INPUT_POST, 'btnGuardar')){ /*propiedades del archivo*/ $archivo_nombre=$_FILES['archivo']['name']; $archivo_tipo = $_FILES['archivo']['type']; $archivo_temp = $_FILES['archivo']['tmp_name']; //conexion con mysql $conn = mysqli_connect('localhost', 'root', '', 'tutoriales-kiuvox') or die("Error al conectar al servidor"); //verificamos si no hay error en la conexion if(!$conn){ $error= mysqli_error($conn); die("ERROR: ".$error["message"]); } //convertir la imagen en código binario $archivo_binario = (file_get_contents($archivo_temp)); /* preparamos la sentencia sql * como observan he declarado unos paramentros en la sentencia sql (?) * que recibiran valores desde el bind_param. * Mas info: * http://php.net/manual/de/mysqli-stmt.bind-param.php */ $sql = "INSERT INTO ARCHIVOS (NOMBRE, TIPO, ARCHIVO) VALUES (?, ?, ?)"; $stmt = mysqli_prepare($conn, $sql); $stmt->bind_param('sss', $archivo_nombre, $archivo_tipo, $archivo_binario); //ejecutamos la sentencia if(mysqli_stmt_execute($stmt)){ echo "Ya guardamos el archivo en la base de datos<br/> Último id insertado: <a href='ver.php?id=". mysqli_stmt_insert_id($stmt)."'>". mysqli_stmt_insert_id($stmt)."</a>"; }else{ echo "Chanfle, hubo un problema y no se guardo el archivo. ". mysqli_stmt_error($stmt)."<br/>"; } mysqli_stmt_close($stmt); mysqli_close($conn); } ?> <!--FORMULARIO--> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <h3>Guardar un archivo en MySQL</h3> <form method="post" action="" enctype="multipart/form-data"> <input type="file" name="archivo" /><br/><br/> <input type="submit" name="btnGuardar" value="Guardar" /> </form> </body> </html> |
Al cargar este archivo seleccionamos el archivo que vamos a insertar en la base y hacemos clic en el botón guardar.
También nos va a interesar el código para recuperar el archivo de la base, con el siguiente solo necesitamos pasar el id del archivo que queremos ver:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php //obtener el id de la imagen $id= filter_input(INPUT_GET, 'id'); if($id==''){ die ("No tenemos el id"); } //conectar a mysql--------- $conn = mysqli_connect('localhost', 'root', '', 'tutoriales-kiuvox') or die("Error al conectar al servidor"); //--------------------------- $sql="SELECT ARCHIVO, TIPO, NOMBRE FROM ARCHIVOS WHERE ID = $id"; //ejecutar la sentencia sql $resultado = mysqli_query($conn, $sql) or die("Error: no se pudo hacer la consulta."); while($row = mysqli_fetch_array($resultado)){ $archivo= $row[0]; //obtener el archivo $tipo=$row[1]; //obtener el tipo de archivo $nombre=$row[2]; //obtener el nombre del archivo } mysqli_close($conn); //header para tranformar la salida en el tipo de archivo que hemos guardado header("Content-type: $tipo"); header('Content-Disposition: attachment; filename="'.$nombre.'"'); //imprimir el archivo echo $archivo; |
Para enviar el id al código lo debemos agregar en la url como este ejemplo:
http://localhost/tutoriales-kiuvox/php/017%20mysql_blob/ver.php?id=1
Si quieren aceptar solo algun tipo de restricción de qué archivos aceptar solo seria necesario que agreguen las condiciones necesarias en funcion de tipo de archivo a recibir.
como defines para acceder al archido de la base de datos en la liga que muestras…
como puedo saber que porcentaje es el de mi archivo?? o como lo defino eso… ?
No estoy completamente seguro de lo que me preguntas, pero aquí te doy una respuesta a ver si le pego.
En el archivo ver.php obtenemos mediante GET el id del archivo que queremos ver, nos conectamos a la base y al query le estamos dando como parámetro el id del archivo y se obtiene los datos de la consulta.
Para poder trasformar lo que viene de la base de datos al archivo como tal debemos agregar unos header, el primero que he puesto le dice al navegador que tipo de archivo esta manejando, el segundo header fuerza al navegador a descargar el archivo con el nombre que tenemos en la base de datos.
Con lo del porcentaje si estoy perdido, no se a que te refieres con eso.
Espero que la respuesta te ayude un poco al menos.
Amigo muchas gracias por el código, pero algo pasa que no me guarda los archivos de imagen o pdf, solo me acepta los txt y los de word, ¿que podrá ser?.
Esto funcionaria con archivos por ejemplo de excel?