Este Howto es acerca de como subir archivos atravez de PHP y guardarlos en MySQL asi como la extracción del archivo de MySQL atravez de PHP.
Requisitos:
Muchas veces necesitamos darle a los usuarios la facilidad de poder “subir” o guardar archivos en una base de datos y n es tan dificil como aparenta asi que comenzemos….
Primeramente necesitamos el diseño de la tabla
y el script para crear la tabla es:
CREATE TABLE tbl_documentos ( id_documento INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, titulo VARCHAR(150) NULL, descripcion MEDIUMTEXT NULL, contenido LONGBLOB NULL, tamanio INTEGER UNSIGNED NULL, tipo VARCHAR(150) NULL, nombre_archivo VARCHAR(255) NULL, tamanio_unidad VARCHAR(150) NULL, PRIMARY KEY(id_documento) );
Explico un poco cada campo para darnos una mayor idea:
Ahora necesitamos un formulario
Aqui esta el codigo del archivo form.html:
<form id="test_upload" name="test_upload" action="upload.php" enctype="multipart/form-data" method="post"> <table border="0" cellpadding="0" cellspacing="0"> <tr> <td> Titulo </td> <td> <input type="text" id="titulo" name="titulo"/> </td> </tr> <tr> <td colspan="2"> Descripcion </td> </tr> <tr> <td colspan="2"> <textarea id="descripcion" name="descripcion" cols="50" rows="5"></textarea> </td> </tr> <tr> <td colspan="2"> Archivo <input type="file" id="archivo" name="archivo"/> </td> </tr> <tr> <td colspan="2"> <input type="submit" value="Registrar Documento"/> </td> </tr> </table> </form>
Al formulario debemos como todos debe tener sus atributos
action que indica el archivo que sse encargara de procesar la información que le enviemos
y method que indica si los datos seran enviados por POST o GET para envio de archivos es obligatorio marcarlo como POST
adicinal a estos atributos debemos especificar enctype con el valor multipart/form-data para que se pueda realizar el envio.
Y aqui esta el codigo del archivo upload.php
< ?php
//ESTA FUNCION LA USAREMOS PARA OBTENER EL TAMAÑO DE NUESTRO ARCHIVO
function filesize_format($bytes, $format = '', $force = ''){
$bytes=(float)$bytes;
if ($bytes< 1024){
$numero=number_format($bytes, 0, '.', ',');
return array($numero,"B");
}
if ($bytes< 1048576){
$numero=number_format($bytes/1024, 2, '.', ',');
return array($numero,"KBs");
}
if ($bytes>= 1048576){
$numero=number_format($bytes/1048576, 2, '.', ',');
return array($numero,"MB");
}
}
//VERIFICAMOS QUE SE SELECCIONO ALGUN ARCHIVO
if(sizeof($_FILES)==0){
echo "No se puede subir el archivo";
exit();
}
// EN ESTA VARIABLE ALMACENAMOS EL NOMBRE TEMPORAL QU SE LE ASIGNO ESTE NOMBRE ES GENERADO POR EL SERVIDOR
// ASI QUE SI NUESTRO ARCHIVO SE LLAMA foto.jpg el tmp_name no sera foto.jpg sino un nombre como SI12349712983.tmp por decir un ejemplo
$archivo = $_FILES["archivo"]["tmp_name"];
//Definimos un array para almacenar el tamaño del archivo
$tamanio=array();
//OBTENEMOS EL TAMAÑO DEL ARCHIVO
$tamanio = $_FILES["archivo"]["size"];
//OBTENEMOS EL TIPO MIME DEL ARCHIVO
$tipo = $_FILES["archivo"]["type"];
//OBTENEMOS EL NOMBRE REAL DEL ARCHIVO AQUI SI SERIA foto.jpg
$nombre_archivo = $_FILES["archivo"]["name"];
//PARA HACERNOS LA VIDA MAS FACIL EXTRAEMOS LOS DATOS DEL REQUEST
extract($_REQUEST);
//VERIFICAMOS DE NUEVO QUE SE SELECCIONO ALGUN ARCHIVO
if ( $archivo != "none" ){
//ABRIMOS EL ARCHIVO EN MODO SOLO LECTURA
// VERIFICAMOS EL TAÑANO DEL ARCHIVO
$fp = fopen($archivo, "rb");
//LEEMOS EL CONTENIDO DEL ARCHIVO
$contenido = fread($fp, $tamanio);
//CON LA FUNCION addslashes AGREGAMOS UN \ A CADA COMILLA SIMPLE ' PORQUE DE OTRA MANERA
//NOS MARCARIA ERROR A LA HORA DE REALIZAR EL INSERT EN NUESTRA TABLA
$contenido = addslashes($contenido);
//CERRAMOS EL ARCHIVO
fclose($fp);
// VERIFICAMOS EL TAÑANO DEL ARCHIVO
if ($tamanio <1048576){
//HACEMOS LA CONVERSION PARA PODER GUARDAR SI EL TAMAÑO ESTA EN b ó MB
$tamanio=filesize_format($tamanio);
}
//CREAMOS NUESTRO INSERT
$qry = "INSERT INTO tbl_documentos ( titulo,nombre_archivo, descripcion, contenido, tamanio,tamanio_unidad, tipo ) VALUES
('$titulo','$nombre_archivo', '$descripcion','$contenido','{$tamanio[0]}','{$tamanio[1]}', '$tipo')";
//NOS CONECAMOS A LA BASE DE DATOS
//REMPLAZEN SUS VALOS POR LOS MIOS
mysql_connect("localhost","root","12345") or die("No se pudo conectar a la base de datos");
//SELECCIONAMOS LA BASE DE DATOS CON LA CUAL VAMOS A TRABAJAR CAMBIEN EL VALOR POR LA SUYA
mysql_select_db("test");
//EJECUTAMOS LA CONSULTA
mysql_query($qry) or die("Query: $qry <br />Error: ".mysql_error());
//CERRAMOS LA CONEXION
mysql_close();
//NOTIFICAMOS AL USUARIO QUE EL ARCHVO SE HA ENVIADO O REDIRIGIMOS A OTRO LADO ETC.
echo "Archivo Agregado Correctamente<br />";
echo 'Subir Otro Archivo<br /> ';
}else{
echo "No fue posible subir el archivo";
echo 'Subir Otro Archivo<br /> ';
}
?>
Ahora que ya tenemos nuestro script funcionando y podemos hacer los uploads que queramos vamos
hacer que se puedan explorar y descargar o mostrar en caso de que sea una imagen.
Primero creamos un archivo que nos imprima el contenido del documento y el tipo del mismo para poder renderizarlo
con este archivo que llamaremos getfile.php
< ?php
//NOS CONECAMOS A LA BASE DE DATOS
//REMPLAZEN SUS VALOS POR LOS MIOS
mysql_connect("localhost","root","12345") or die("No se pudo conectar a la base de datos");
//SELECCIONAMOS LA BASE DE DATOS CON LA CUAL VAMOS A TRABAJAR CAMBIEN EL VALOR POR LA SUYA
mysql_select_db("test");
//CONSTRUIMOS LA CONSULTA PARA OBTENER EL DOCUMENTO
$qry="Select * from tbl_documentos where id_documento={$_REQUEST['id_documento']}";
$res=mysql_query($qry) or die(mysql_error()." qry::$qry");
$obj=mysql_fetch_object($res);
//OBTENEMOS EL TIPO MIME DEL ARCHIVO ASI EL NAVEGADOR SABRA DE QUE SE TRATA
header("Content-type: {$obj->tipo}");
//OBTENEMOS EL NOMBRE DEL ARCHIVO POR SI LO QUE SE REQUIERE ES DESCARGARLO
header('Content-Disposition: attachment; filename="'.$obj->nombre_archivo.'"');
//Y PO ULTIMO SIMPLEMENTE IMPRIMIMOS EL CONTENIDO DEL ARCHIVO
print $obj->contenido;
//CERRAMOS LA CONEXION
mysql_close();
?>
Posteriormente crearemos un archivo para que nos liste los documentos registrados y
detecte si es una imagen en este caso imprimiremos un tag img y su src sera nuestro archivo getfile.php
cuando incluimos un archivo con php podemos pasarle parametros cono si se tratara de un query string del browser asi que le pasaremos el id_documento
para que nos muestre el archivo solicitado.
Este es e código de nuestro archivo list.php
< ?php
//NOS CONECAMOS A LA BASE DE DATOS
//REMPLAZEN SUS VALOS POR LOS MIOS
mysql_connect("localhost","root","12345") or die("No se pudo conectar a la base de datos");
//SELECCIONAMOS LA BASE DE DATOS CON LA CUAL VAMOS A TRABAJAR CAMBIEN EL VALOR POR LA SUYA
mysql_select_db("test");
//CONSTRUIMOS EL QUERY PARA OBTENER LOS ARCHIVOS
$qry="select
docs.*,
CASE docs.tipo
WHEN 'image/png' then
'image'
WHEN 'image/jpg' then
'image'
WHEN 'image/gif' then
'image'
WHEN 'image/jpeg' then
'image'
ELSE
'file'
END as display
from tbl_documentos AS docs";
//EJECUTAMOS LA CONSULTA
$res=mysql_query($qry) or die("Query: $qry ".mysql_error());
//RECORREMOS LA CONSULTA
//*********NOTA DONDE DICE alt='$obj-/>titulo' QUITA LA BARRA PARA QUE QUEDE ASI:
// alt='$obj->titulo'
// EL WORDPRESS ME ESTA REMPLAZANDO EL CODIGO
while ($obj=mysql_fetch_object($res)) {
//SI EL TIPO DE DOCUMENTO ES UMAGEN LA MOSTRAMOS SI NO SOLO HACEMOS EL LINK
switch ($obj->display){
case "image":
echo "<div>
<a href='getfile.php?id_documento={$obj->id_documento}'>
<img alt='$obj-/>titulo' src='getfile.php?id_documento={$obj->id_documento}'/>
</a>
</div><hr />";
break;
case "file":
echo "<div>
<a href='getfile.php?id_documento={$obj->id_documento}'>$obj->titulo</a>
</div><hr />";
break;
}
}
//CERRAMOS LA CONEXION
mysql_close();
?>
Ahora solo abrimos nuestro explorador con loas sigueintes direcciones:
Descargar los archivos del howto de este
Y con esto terminamos este pequeño howto de como manejar archivos con php y MySQL
espero les sirva y cualquier comentario queja o sugerencia porfavor haganla saber asi como alguna duda que tengan y se pueda convertir en un howto
sera tomada en cuenta.
Cudense …
dulce desde
hola, tengo un codigo similar a este, al borrar tengo un problema ya no puedo agregar mas, lo borro con un simple delete si no con que mas ??
muchas gracias :D
Responder
Ruben Omar desde
Hola gracias por comentar…
Como estas borrando las filas? yo lo hago con un simple :
[php]
$strSQLBorrar=”DELETE FORM documentos where id_documento=$id_doc”;
mysql_query($strSQLBorrar);
[/php]
Responder
Pablo [masTecno] desde
Muy inytersantel; esta como para archivar :)
Responder
cecilia desde
Parse error: syntax error, unexpected ‘;’ in D:\servidor\web\test\upload.php on line 5
ilinea 5 : if ($bytes <1024){
Responder
Ruben Omar desde
Ups perdon fue un fallo del coloreador de sintaxis checalo nuevamente porfavor
Responder
frehd desde
Hola queria saber cual es el tamaño maximo permitido para cada archivo.
Soy nuevo en esto de la programacion y la verdad que te agradezco por compartir tus conocimientos. :-)
Responder
Ruben Omar desde
frehd:
Gracias por el comentario mira acabo de escribir un pequeño articulo echale un vistazo:
http://blog.deliriumlabs.net/2008/03/20/php-snippet-max-upload-file-size/
Responder
voodoo desde
Hola:
tu articulo esta muy bien explicado.
Hace un tiempo puse en mi blog un articulo sobre este tema
http://fabianperez.blogspot.com/2007/11/php-y-mysql-manejo-de-bases-de-datos.html
pero debo decir que tu explicacion es muy clara. Ademas noto que tienes gran conocimiento del tema y que respondes a los comentarios para ayudar.
Felicitaciones
Responder
Ruben Omar desde
1000 gracias por los comentarios :D, que al fin estamos para ayudarnos entre todos
Responder
bettencourt desde
Buenas viendo este ejemplo me gustaría preguntarte algo para saber si es posible realizarlo en php, veo que aquí archivas un documento en php, ves su tamaño y lo visionas en caso de que sea una foto, podrias visionarlo si fuera un documento y luego de alguna forma guardarlo en un array de strings para poder realizar busquedas sobre ese documento?, gracias por adelantado.
Responder
Ruben Omar desde
A que te refieres con visionarlo?
Obtener el contenido?
Responder
Titux desde
Que tal, primero que nada, quisiera saber que quieres decir con VISIONAR, despúes, que es lo que quieres hacer en general.
Saludos…
Responder
bettencourt desde
el visionar o no realmente me da lo mismo, lo ke intento es poder meter el contenido de un documento de texto, en un array de strings, de forma que pueda realizar busquedas sobre ese documento
Responder
Ruben Omar desde
Dijo:
Ok dejame ver si ya entendi el procedimiento que quieres es asi:
1.- Subir un archivo de texto solo podra ser con un .TXT.
2.- Leer el contenido del archivo y guardarlo en el campo de una tabla.
3.- Guardar el archivo en binario.
Ya con esto se podra hacer un formulario de busqueda para para que muetre una lista de los archivos que muetren el criterio de busqueda.
Es esto lo que quieres hacer?
Corrigeme si me equivoco.
Responder
bettencourt desde
es mas o menos eso si lo ke no entiendo por ke los guardaras en binario y una pekeña apreciacion los criteriios de busqueda se los dare yo, no seran por formulario debe ser totalmente automatico y mostrara el texto que viene detras de la palabra ke anda buscando, pero si es eso ke tu dices, no te ekivocas, lo ves posible de hacer? podrias guiarme para dar esos primeros 3 pasos?, gracias de antemano, bye
Responder
Ruben Omar desde
OK. claro que es posible, el proximo viernes públicare el articulo enfocado exactamente en este procedimeinto.
Saludos
Responder
Ruben Omar desde
Otra cosa tendras algun archivo de texto de ejemplo que me puedas proporcionar?
Responder
bettencourt desde
Joder, no sabes cuanto te lo agradeceria si lo pudieras hacer me un grandisimo favor, supongo ke si ke te puedo pasar algo ke te sirva como ayuda, pero por donde te lo paso?
Responder
Ruben Omar desde
Enviamelo a mi direccion de correo: deliriumlabs@deliriumlabs.net
Responder
jessy desde
Muy buen artículo.
Me ha sido de gran ayuda ;)
Responder
Lucho desde
Muy bueno! Me ha sido de mucha utilidad. Ahora… disculpen mi ignoracia, ya que no sé mucho del tema, pero donde se alojarían los archivos que se suben…?
Responder
Ruben Omar desde
En este tutorial lo estamos alojando en la base de datos
Responder
facu desde
Hola amigo, muy bueno el articulo, queria hacer una pregunta, si tienes algun articulo o puedes hacer uno, donde se almacene una imagen jpg por ejemplo, en una carptea del servidor y en la base de datos se almacene solo la ruta de dicha imagen, un saludo!!
Responder
JUANCHO desde
Muy claro, lo probare a ver que tal.
Responder
SpiderNet desde
Hola………….Excelente!!!
Esta muy bien explicado el tutorial.
Pero tengo un problemita al ejecutar el archivo getfile.php me da el siguiente error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” at line 1 qry::Select * from tbl_documentos where id_documento=
Uso la versión 5.0.5.1a de MySQL.
La parte de subir archivos no dio ningun error, pero este (getfile.php) si.
Que podría estar pasando???
Saludos!!!
Espero puedas ayudarme
Responder
Ruben Omar desde
Dijo:
Hola, disculpas por la tardanza en contestar.
Al parecer es solo que no estas enviando la variable id documento. si me pudieras enviar tus archivos y te los reviso.
Responder
Ildefonso desde
esta bien tu codigo, pero como le hago para ver el archivo y subi, o algo asi
Responder
Ruben Omar desde
Dijo:
Hola, en el tutorial tambien explico como crear el archivo list.php
Responder
Manuel desde
Muy interesante
Responder
Ruben Omar desde
Dijo:
Gracias
Responder
Mig desde
De pok, gracias Mister fue muy util
Responder
lamek desde
Hola, me da un error en la linea 49 del archivo upload.php
Dice esto.:
Parse error: syntax error, unexpected ‘;’ in C:wampwwwupload.php on line 49
A que se debe?
Responder
Ruben Omar desde
Dijo:
enviame tu archivo a blog@deliriumlabs.net para checarlo
Responder
lamek desde
Dijo:
Ok.
Responder
Ruben Omar desde
Dijo:
Ya encontre el detalle en la linea 49 del archivo upload
$tamanio <10485760000
reemplaza $lt por <
el wordpress me remplazo el caracter por eso no te esta funcionando
edgardo desde
hola la verdad me facilitaste mucho las cosas, por que tenia miedo por seguridad de abrirles un camino a los tantos que pierden tiempo dañando sitios haciendo un upload comun al servidor.
Muchas gracias de enserio !!!!
Ahora al final con el error del getfile.php que paso ?? por que a mi me sale tambien.. debe ser por el tipo de servidor no soporta la syntax
Error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ” at line 1 qry::Select * from tbl_documentos where id_documento=
Codigo del getfile:
tipo}”);
//OBTENEMOS EL NOMBRE DEL ARCHIVO POR SI LO QUE SE REQUIERE ES DESCARGARLO
header(‘Content-Disposition: attachment; filename=”‘.$obj->nombre_archivo.’”‘);
//Y PO ULTIMO SIMPLEMENTE IMPRIMIMOS EL CONTENIDO DEL ARCHIVO
print $obj->contenido;
//CERRAMOS LA CONEXION
mysql_close();
?>
Desde ya muchas gracias..
Responder
Ruben Omar desde
Dijo:
Solo debes asegurate que estas enviando la variable id_documento ya sea por medio de GET en un link o POST en un formulario
Responder
Mike desde
Gracias por este ejemplo muy buena la explicación.
me sirvió bastante, se me aclararon varias dudas.
Responder
milito88 desde
Uyyyy q buen articulo este me acabas de salvar de un rollo grandisimo
Responder
jtaquichiri desde
Funciona con archivos menor a 2 mb cuando subo un archivo mayor a 2 mb no funciona tengo que cambiar algo en el script o cambiar la configuracion de mysql o php uso php uso el appserver
Responder
Anthraxnet desde
Enhorabuena por tu tutorial, me parece muy completo y muy bueno, pero me da el problema que al ejecutarlo me da un error de Apache y se me cierra, no se si puede deberse a un error en el script o hay algo que debo cambiar pero me interesaría muchisimo saber cual es el problema ya que otras páginas dentro del mismo site, me funcionan perfectamente.
Gracias y un saludo
Responder
Ruben Omar desde
Dijo:
Hola que error te marca?
Responder
Anthraxnet desde
Dijo:
Segun el log del apache me sale lo siguiente
[Tue Dec 22 09:32:38 2009] [error] [client 127.0.0.1] File does not exist: C:/wamp/www/favicon.ico
[Tue Dec 22 09:32:41 2009] [error] [client 127.0.0.1] File does not exist: C:/wamp/www/favicon.ico
[Tue Dec 22 09:33:05 2009] [notice] Parent: child process exited with status 3221225477 — Restarting.
y como te comento se cierra. Esto me pasa con todas las paginas que se dedican al manejo de archivos que saque de tu tutorial.
Responder
austin desde
Muy buena info amigo, podria poner un tutorial como guardar el archivo fuera de la db y en la bd solo la ruta al archivo??
gracias
salu2
Responder
Constanza desde
No solo quiero felicitarte, si no darte las gracias, me has sido de gran ayuda ya que estoy en mis inicios del tratamiento web i sql
Responder