Como resultado de investigar, me di cuenta que existen dos formas de guardar imágenes en la base de datos. La primera, y al parecer la más complicada, es creando un campo de tipo blob para la imagen. La otra, más sencilla, es subir la imagen a una carpeta en el servidor con la función php llamada move_uploaded_file() y posteriormente guardar la ruta de la imagen en la base de datos. Cabe mencionar que la ruta es una cadena de texto, sin mayor complicación. 😀
Para obtener el directorio de trabajo completo de este ejemplo incluyendo el bootstrap.css, la librería fpdf y el jquery en sus carpetas correspondientes, puedes descargar de este enlace directo de dropbox (click en saltar publicidad y te lleva directo a la descarga)
Lo primero que se ha de hacer es crear un árbol de directorios como el que se muestra continuación y colocar los archivos en el lugar correspondiente.
Sin más, empecemos haciendo el HTML5 y el CSS para ver cómo quedará nuestro formulario para pedir un nick, mail y elegir una imagen. Acá el formulario:
El index.php con el formulario es el siguiente:
<?php /* Por el momento esto debe estar comentado error_reporting(0); include_once('php/myDBC.php'); $objeto = new myDBC(); $imagenes = $objeto->seleccionar_images(); */ ?> <!DOCTYPE html> <html> <head> <title>huguidugui.wordpress.com</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"> <link rel="stylesheet" type="text/css" href="css/estilos.css"> </head> <body> <div class="wrap"> <header> Subir Archivos con PHP y MySQL </header> <section id="principal"> <form id="formulario" action="php/subir.php" method="POST" enctype="multipart/form-data"> <div class="campos"> <label > Nick </label> <input type="text" name="nombre" required/> </div> <div class="campos"> <label> Mail </label> <input type="email" name="apellido" required/> </div> <div class="campos"> <label> Edad </label> <input type="number" min="15" max="70" name="apellido" required/> </div> <div class="campos"> <label for="imagen">Imagen:</label> <input type="file" name="hugo" id="imagen" /> <input type="submit" name="subir" value="Subir"/> </div> </form> </section> <section id="mostrar_imagenes"> <?php /* Esto debe estar comentado foreach($imagenes as $imagen){ echo '<div class="todas">'; echo '<img src="'.$imagen['ruta'].'"/>'; echo '</div>'; } ?> */ </section> </div> </body> </html>
Ahora agregamos el CSS:
*{ margin: 0; padding: 0; } body { background: url(../images/bg.png) repeat; border: 0; margin: 0; padding: 0; } .wrap { margin: 0 auto; width: 80%; } header { background: #33BBAA; padding: 20px 0; margin: 15px 0; text-align: center; font-size: 33px; color: #99ff00; border-radius: 10px; line-height: 35px; width: 100%; } #principal{ margin-bottom:10px; background: #44AA00; padding: 20px 0; border-radius: 10px; width: 100%; } #mostrar_imagenes{ margin-bottom:10px; background: #CC00F0; padding: 20px 0; border-radius: 10px; width: 100%;} .campos, .campos label, .campos input{ float:left; padding: 0px; width: 100%; } #formulario{ border-radius: 10px; margin: 0 auto; padding:10px 20px 10px 10px; border: 1px solid; overflow:hidden; width: 35%; } .todas{ display: inline-block; } .todas img{ margin: 10px 10px; width: 50px; height: 50px; }
Así se verá:
Como podrán notar en el código, se agregaron validaciones del propio HTML5 para validar texto y que no esté vacío el campo (en el nick), validación de mail y validación de de un rango de edad. Esto es lo más notable que tiene HTML5 😀
Ahora viene lo «complicado» que será subir el archivo de imagen a un carpeta local del servidor que llamaremos ‘imagenes’ que se hará mediante la función move_uploaded_file() de php y en seguida, subir la información del formulario a la base de datos con ayuda de los archivos myDBC.php. Peeeeeeeeeero… antes de subir cualquier archivo al servidor, lo que debemos hacer como buenos programadores, es validar dicho archivo subido. En este caso tenemos que validar ciertas características, como por ejemplo definir un tamaño máximo en Mb, verificar que sea una imagen, verificar que no haya un archivo con el mismo nombre ya subido en la carpeta. Bueno, todo esto que acabo de mencionar se resume en este pseudo-código, el cual me ayudo bastante antes de seguir con la codificación en php. Ojalá les sirva también:
Ahora el código de subir.php que se hace cargo del formulario. También les sugiero visitar este enlace PHP File Upload donde explica rápido y sencillo el manejo de la matriz $_FILES
<?php include('myDBC.php'); //Definir Tamaño de archivo 5MB define('LIMITE', 5000); //Definir arreglo con extensiones permitidas usar serialize define('ARREGLO', serialize( array('image/jpg', 'image/jpeg', 'image/gif','image/png'))); $PERMITIDOS = unserialize(ARREGLO); //Usar unserialize para obtener el arreglo $subirInformacion = new myDBC(); //Objeto para conexión a BD if ($_FILES["hugo"]["error"] > 0){ echo'<script type="text/javascript"> alert("Error de FILE Selecciona un Archivo"); window.location="http://localhost/subirArchivos/index.php" </script>'; } else { if (in_array($_FILES['hugo']['type'], $PERMITIDOS) && $_FILES['hugo']['size'] <= LIMITE * 1024){ //Desde subir.php a la carpeta imagenes hay que salir un directorio //../imagenes/nombreDeArchivo $rutaEnServidor = "../imagenes/" . $_FILES['hugo']['name']; //Desde index.php, la carpeta imagenes está en imagenes/nombreDeArchivo $ruta = "imagenes/" . $_FILES['hugo']['name']; if (!file_exists($ruta)){ $resultado = move_uploaded_file($_FILES["hugo"]["tmp_name"], $rutaEnServidor); if ($resultado){ $name = $_POST['nombre']; $ape = $_POST['apellido']; $subirInformacion->subirTodo($name, $ape, $ruta); }else { echo'<script type="text/javascript"> alert("Ocurrió un error al mover archivo"); window.location="http://localhost/subirArchivos/index.php" </script>'; } }else{ echo'<script type="text/javascript"> alert("Este archivo ya existe en la BD"); window.location="http://localhost/subirArchivos/index.php" </script>'; } }else { echo'<script type="text/javascript"> alert("Tipo de archivo no permitido o excede tamaño"); window.location="http://localhost/subirArchivos/index.php" </script>'; } } ?>
Es necesario agregar en la carpeta PHP los siguientes archivos: dbconfig.php y myDBC.php que son archivos usados anteriormente en otros tutos pero que de todos modos acá se los dejo: el primero es simplemente la configuración a su base de datos y el segundo es el encargado de hacer la inserción y las consultas. Es cuestión de que lo analicen y vean su funcionamiento.
dbconfig.php
<?php define("DB_SERVER", "localhost"); define("DB_USER", "root"); define("DB_PASS", ""); define("DB_NAME", "imagenes"); ?>
myDBC.php
<?php class myDBC{ public $mysqli=null; public function __construct(){ include_once 'dbconfig.php'; $this->mysqli = new mysqli(DB_SERVER, DB_USER, DB_PASS, DB_NAME); if ($this->mysqli->connect_errno){ echo "Error MySQLi: (" . $this->mysqli->connect_errno.") " . $this->mysqli->connect_error; exit(); } $this->mysqli->set_charset("utf8"); } public function __destruct(){ $this->CloseDB(); } public function runQuery($qry){ $result = $this->mysqli->query($qry); return $result; } public function CloseDB(){ $this->mysqli->close(); } public function clearText($text){ $text = trim($text); return $this->mysqli->real_escape_string($text); } public function subirTodo($nombre, $mail, $ruta){ $q = "INSERT INTO imagenes (nombre, email, ruta) VALUES ('$nombre', '$mail', '$ruta')"; $result = $this->mysqli->query($q); if($result){ //Si resultado es true, se agregó correctamente echo'<script type="text/javascript"> alert("Agregado Exitosamente a la BD"); window.location="http://localhost/subirArchivos/index.php" </script>'; } else{ //Si hubo error al insertar, se avisa echo'<script type="text/javascript"> alert("Chispas... Algo anda mal"); window.location="http://localhost/subirArchivos/index.php" </script>'; } } public function seleccionar_images(){ $q = "select ruta from imagenes"; $result = $this->mysqli->query($q); //Array asociativo que contendrá los datos $valores = array(); //Si no hay resultados //Se avisa al usuario y se redirige al index de la aplicación if( $result->num_rows == 0) { echo'<script type="text/javascript"> alert("Ningun registro"); </script>'; return false; } //En otro caso, se recibe la información y se //se regresa un array con los datos de la consulta else{ while($row = mysqli_fetch_assoc($result)){ //Se agrega cada valor en el array array_push($valores, $row); } } //Regresa array asociativo return $valores; } } ?>
Para continuar con el ejemplo es necesario crear una base de datos como la que se muestra continuación y quitar los comentarios.
Acá una secuencia de uso en imágenes:
figardi
27 julio, 2014 at 21:28
Hola muy bueno este código, sabrá como hacerlo con varias imágenes?
o sabe de algún código que haga lo mismo pero con más imágenes?
saludos Fidel
A Fernando ZC
4 agosto, 2014 at 22:53
Gracias despues de tanto buscar di con este blog , exelente explicación
huguidugui
5 agosto, 2014 at 08:33
Agradezco mucho tu felicitación y me alegra que te haya servido 😀
Saludos
Dayana Flores
18 septiembre, 2014 at 06:52
Hola buenos dias amigos. He estado leyendo ultimamente sobre un tema que me interesa: el Diseño Sensible o Responsive Web Design. Trabajo en una Universidad la cual tiene ya su página hecha desde hace algun tiempo. Quiero saber como hago para convertir esa página que ya esta hecha en un diseño sensible para que se pueda ver en cualquier dispositivo y se adapte. Si tienes un tutorial te lo agradezco. Trabajo por el Framework Kumbia y PHP5. Gracias
huguidugui
10 octubre, 2014 at 06:17
Hola Dayana 😀
Perdón por haber contestado tan tarde 😉
TE enviaré a tu correo unos sitio de internet en el que puedes aprender muy bien el diseño responsivo, en el que vienen ejemplos desde lo más básicos hasta complejos, todos con ejemplos en línea que puedes visualizar en el instante.
Saludos hasta Venezuela 😀
Jaz
21 octubre, 2014 at 16:39
Muy buena informacion, me sirvio mucho, gracias y pedirte los sitio sde internet que recominedas para el diseño responsivo, me interesa mucho te dejo mi correo
huguidugui
22 octubre, 2014 at 18:09
Hola Jaz, no tengo un sitio que pueda recomendar. Pero la verdad es que para aprender diseño resposive te tienes que bajar plantillas y ver cómo funcionan quitando/poniendo reglas del CSS. Así te vas dando cuenta qué hace tal regla.
alex
28 septiembre, 2014 at 14:45
Sabrías como mostrar además de la imagen por el ejemplo el nombre y a la vez subir más fotos
huguidugui
29 septiembre, 2014 at 06:03
Hola Alex, de hecho, ese será el próximo tuto que saldrá dentro de poco tiempo.
Saludos y gracias por leer el blog 😀
otniel
11 marzo, 2015 at 10:25
Amigo muy bueno tu tutorial, estoy estudiandolo, pero tengo una duda, donde esta tu archivo de la base de datos? ya que descargue el ejemplo «generarGafetes» de tu DropBox, pero al intentar verlo me aparece esto en el index.php:
Dbr`0 9Dh* (
huguidugui
12 marzo, 2015 at 07:04
Hola otniel, muy buena observación… En fin de semana vuelvo a subir todos los zip de los ejemplos con sus bases de datos respectivas.
Gracias 😀
che
19 abril, 2015 at 17:58
gracias por el aporte muy buen trabajo
huguidugui
19 abril, 2015 at 21:12
Gracias 😀
Josh
23 junio, 2015 at 12:28
Disculpa como podria hacer que mediante una lista desplegable si por ejemplo el usuario selecciona «comida» la imagen que quiera subir se guarde en una carpeta con dicho nombre.
Gracias de antemano. Y genial tutorial!
huguidugui
25 junio, 2015 at 06:03
Hola Josh, pues así como lo planteas, lo que viene a la mente es hacer el select con las opciones y en el value el nombre de la carpeta que requieras ahí en el formulario, después obtener ese valor (que también es de POST) verificar dicho value (carpeta) con if’s o un switch y crearla ruta a la carpeta específica que requieras que se guarde el archivo.
Si quieres ya tienes código hecho, te puedo ayudar. Envíame tu código a ringhugos@gmail.com
Saludos y gracias por leerel blog.
Ignacio
22 agosto, 2015 at 10:39
Gracias por compartir los archivos, lo probaré revise de pasada y parece que es la nueva extensión de mysqli, muchas gracias.
huguidugui
23 agosto, 2015 at 11:07
Hola, sí mysqli es la nueva extensión por default para usar. Saludos y gracias por leer el blog
Paulino Trejo
27 junio, 2017 at 10:40
hola que tal bueno no se si en realidad leerás los comentarios después de tanto tiempo pero quiero agradecerte ya que tu ejemplo me ayudo mucho, es cierto eso de si quieres aprender algo realiza paso a paso no solo lo copies por que te quedas en lo mismo no aprendes nada, bueno gracias y saludos.
axel ajin
14 septiembre, 2017 at 11:27
Amigo muy buen código estando en el 2017 me funciono bastante bien, gracias.