Bueno, visto las recurrentes preguntas sobre como guardar un archivo binario (sea una imagen, un .exe .. o lo que sea) en una Base de datos (Mysql) y guardando integramente el archivo en un campo de la BD .. aquí va un ejemplo completo.
Se usa el array $_FILES[] ... así q solo funcionará bajo PHP 4.1.x o superior .. Por supuesto, el "Upload" de archivos ha de estar habilitado y configurado en el servidor que se use ..
Más info sobre configuración del tema "Upload":
http://www.php.net/manual/en/features.file-upload.php
Es muy básico el sistema .. pero está completo. Faltan muchos detalles de validación.
Si quieren añadir mas datos adjuntos al archivo que suban .. solo tienen que añadir mas campos a la tabla 'archivos' y modificar las consultas implicadas (SQL) junto con el própio formulario HTML (tan solo añadir sus campos extra ..)
El código se divide en varios scripts .. El nombre de cada uno creo q es bastante explicativo .. cualquier duda .. pregunten:
Estructura SQL de la tabla que vamos a emplear:
Código:
#
# Estructura de tabla para la tabla `archivos`
#
CREATE TABLE archivos (
id int(10) unsigned NOT NULL auto_increment,
archivo_binario blob NOT NULL,
archivo_nombre varchar(255) NOT NULL default '',
archivo_peso varchar(15) NOT NULL default '',
archivo_tipo varchar(25) NOT NULL default '',
PRIMARY KEY (id)
) TYPE=MyISAM;
formulario.php Código PHP:
<HTML>
<HEAD>
<TITLE>Binario a BD</TITLE>
</HEAD>
<BODY>
<?php
if (isset($_GET['proceso'])){
echo $_GET['proceso']."<br>";
}
?>
<FORM enctype="multipart/form-data" method="post" action="insertar.php">
Archivo: <INPUT type="file" name="archivo" size="30">
<INPUT type="submit" name="submit" value="Subir archivo">
</FORM>
</BODY>
</HTML>
insertar.php Código PHP:
<?php
//Primero, arranca el bloque PHP y checkea si el archivo tiene nombre. Si no fue asi, te remite de nuevo al formulario de inserción:
// No se comprueba aqui si se ha subido correctamente.
if (empty($_FILES['archivo']['name'])){
header("location: formulario.php?proceso=falta_indicar_fichero"); //o como se llame el formulario ..
exit;
}
//establece una conexión con la base de datos.
$conexion = mysql_connect("localhost","","") or die("No se pudo realizar la conexion con el servidor.");
mysql_select_db("tu_bd",$conexion) or die("No se puede seleccionar BD"); // tu_bd es el nombre de la Base de datos .. por siaca.
// archivo temporal (ruta y nombre).
$binario_nombre_temporal=$_FILES['archivo']['tmp_name'] ;
// leer del archvio temporal .. el binario subido.
// "rb" para Windows .. Linux parece q con "r" sobra ...
$binario_contenido = addslashes(fread(fopen($binario_nombre_temporal, "rb"), filesize($binario_nombre_temporal)));
// Obtener del array FILES (superglobal) los datos del binario .. nombre, tabamo y tipo.
$binario_nombre=$_FILES['archivo']['name'];
$binario_peso=$_FILES['archivo']['size'];
$binario_tipo=$_FILES['archivo']['type'];
//insertamos los datos en la BD.
$consulta_insertar = "INSERT INTO archivos (id, archivo_binario, archivo_nombre, archivo_peso, archivo_tipo) VALUES ('', '$binario_contenido', '$binario_nombre', '$binario_peso', '$binario_tipo')";
mysql_query($consulta_insertar,$conexion) or die("No se pudo insertar los datos en la base de datos.");
header("location: listar_imagenes.php"); // si ha ido todo bien
exit;
?>
ver.php
Se puede usar directamente llamandolo via un tag HTML de imagen:
<img src="ver.php?id=nºregistro_archivo">
Código PHP:
<?php
if(isset($_GET['id'])) {
// you may have to modify login information for your database server:
$conexion=mysql_connect("localhost","","") or die ("no se ha podido conectar a la BD");
mysql_select_db("tu_bd") or die ("no se ha podido seleccionar la BD");
$sql = "SELECT archivo_binario,archivo_tipo FROM archivos WHERE id='".$_GET['id']."'";
$consulta = mysql_query($sql,$conexion);
$datos = mysql_result($consulta,0,"archivo_binario");
$tipo = mysql_result($consulta,0,"archivo_tipo");
header("Content-type: $tipo");
echo $datos;
}
?>
listar_imagenes.php
Un ejemplo completo orientado a listar imagenes (todas) las que contenga nuestra BD junto con el resto de información sobre el archivo que hemos guardado ..
Código PHP:
<?php
mysql_connect("localhost","","") or die ("no se ha podido conectar a la BD");
mysql_select_db("tu_bd") or die ("no se ha podido seleccionar la BD");
$sql = "SELECT id,archivo_nombre,archivo_tipo,archivo_peso FROM archivos";
$consulta = mysql_query($sql) or die ("No se pudo ejecutar la consulta");
While ($registro=mysql_fetch_assoc($consulta)){
echo "<img src=\"ver.php?id=".$registro['id']."\">";
echo "<br> Nombre archivo: ".$registro['archivo_nombre'];
echo "<br> Tipo archivo (MIME formato): ".$registro['archivo_tipo'];
echo "<br> Peso: ".$registro['archivo_peso']." bytes.<br><br>";
}
?>
Y .. otro ejemplo de uso. En este caso se trata de generar "thumbnails" (imagenes pequeñas desde una origen a tamaño real) de las imagenes de la BD.
El uso sería igual que el ver.php. Usa las librerías gráficas GD 1.x en adelante de PHP.
ver_thumbnail.php Código PHP:
<?php
// OJO, sólo funciona con imagnes en formato JPEG ...
if(isset($_GET['id'])) {
$conexion=mysql_connect("localhost","","") or die ("no se ha podido conectar a la BD");
mysql_select_db("tu_bd") or die ("no se ha podido seleccionar la BD");
$sql = "SELECT archivo_binario,archivo_tipo,archivo_nombre FROM archivos WHERE id='".$_GET['id']."'";
$consulta = mysql_query($sql,$conexion);
$imagen = mysql_result($consulta,0,"archivo_binario");
// Envio cabeceras al navegador .. se indica que lo "que vá" es una imagen de formato MIME JPEG
Header ("Content-type: image/jpeg");
// Generar el thumbnail:
// Se crea la imagen desde el campo binario de la BD
$img = imagecreatefromstring($imagen);
// Tamaño del Thumbanil (de la imagen a generar ..)
$picsize = 123;
// Se obtienen los datos del ancho y alto de la imagen.
$new_w = imagesx($img);
$new_h = imagesy($img);
// Se calcula la relación alto/ancho
$aspect_ratio = $new_h / $new_w;
// Se ajusta al nuevo tamaño
$new_w = $picsize;
$new_h = abs($new_w * $aspect_ratio);
// Se crea la mascara de la imagen nueva
$dst_img = imagecreate($new_w,$new_h);
// Se copia y reajusta el nuevo tamaño en la nueva imagen.
imagecopyresized($dst_img,$img,0,0,0,0,$new_w,$new_h,imagesx($img),imagesy($img));
// Se entrega al buffer de salida (navegador en este caso) la imagen en formato JPEG
// El tercer parámetro (100) indica la calidad de la imagen: en porcentaje relación calidad/peso imagen.
imagejpeg($dst_img,'',100);
}
?>
Si usan GD versión 2.x pueden sustituir el código de estos bloques por:
Código PHP:
// Se crea la mascara de la imagen nueva
$dst_img = ImageCreateTrueColor($new_w,$new_h);
// Se copia y reajusta el nuevo tamaño en la nueva imagen.
imagecopyresampled($dst_img,$img,0,0,0,0,$new_w,$new_h,imagesx($img),imagesy($img));
Con lo cual se ganará en profundidad de color (=mejor calidad ..)
NOTA: El artículo está usando campos tipo BLOD para almacenar el archivo binario. Su limite es de 65535 bytes (64 Kbytes), si desean almacenar archivos de peso superior deben de cambiar el tipo de campo "archivo_binaro" a un MEDIUMBLOB (16Mbytes max.) o a un LONGBLOB (4 Gbytes). Más info al respecto en:
http://www.mysql.com/doc/en/Column_types.html Actualización (18/08/2004): Solventado problema (bug) en la creación de los "thumbnails". El recurso de imagen para imagesx() e imagesy() no era $src_img sino $img.
Un saludo,