RSS

Subir y guardar imágenes en la BD

25 Jun

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.

arbol_directorios

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á:

responsive_full

Pantalla completa

responsive_medio

Pantalla a la mitad

responsive_minum

Pantalla mínima

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:

pseudocodigo

Pseudo-código del archivo subir.php

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: ("&nbsp. $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.

bd_estructure

 

Acá una secuencia de uso en imágenes:

campos_llenos

Campos llenos

archivo_subido

Algunos registros

bd_datos

Algunos registros en la base de datos

 

 
19 comentarios

Publicado por en 25 junio, 2014 en HTML, CSS, JQUERY, PHP

 

Etiquetas: , , , ,

19 Respuestas a “Subir y guardar imágenes en la BD

  1. 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

     
  2. 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

       
  3. 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.

         
  4. 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 😀

       
  5. 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 😀

       
  6. che

    19 abril, 2015 at 17:58

    gracias por el aporte muy buen trabajo

     
  7. 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.

       
  8. 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

       
  9. 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.

     
  10. axel ajin

    14 septiembre, 2017 at 11:27

    Amigo muy buen código estando en el 2017 me funciono bastante bien, gracias.

     

Replica a huguidugui Cancelar la respuesta