jueves, 27 de junio de 2019

Grabar y mostrar imágenes con PHP y MySQL


El presente tutorial nos mostrará como almacenar imágenes en MySQL utilizando PHP

Herramientas usadas

  • WAMP - Versión 3.1.7
  • Apache - Versión 2.4.37
  • PHP - Versión 7.3.1
  • MySQL - Versión 5.7.24
  • MariaBD - Versión 10.3.12
Se puede utilizar MySQL o MariaBD, simplemente cambiar el puerto 3306 del MySQL por el 3307 de MariaBD.

Base de datos utilizada

  1. -- TABLA ESTADO
  2. CREATE TABLE estado (
  3. id INT NOT NULL AUTO_INCREMENT ,
  4. nombres VARCHAR(100) NOT NULL ,
  5. PRIMARY KEY (id)
  6. )ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_general_ci;
  7. /* DATOS DE INICIO */
  8. INSERT INTO estado(nombres) VALUES
  9. ('soltero'),
  10. ('casado'),
  11. ('divorciado'),
  12. ('viudo')
  13. -- TABLA PERSONAS
  14. CREATE TABLE personas (
  15. id INT NOT NULL AUTO_INCREMENT ,
  16. paterno VARCHAR(150) NOT NULL ,
  17. materno VARCHAR(150) NOT NULL ,
  18. nombres VARCHAR(100) NOT NULL ,
  19. estado INT NOT NULL ,
  20. foto MEDIUMBLOB NULL ,
  21. fecha_nacimiento DATE NOT NULL ,
  22. PRIMARY KEY (id), /* CLAVE PRIMARIA */
  23. CONSTRAINT fk_estado /* CLAVE FORÁNEA */
  24. FOREIGN KEY (estado)
  25. REFERENCES estado (id)
  26. ON DELETE NO ACTION
  27. ON UPDATE NO ACTION
  28. )ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_general_ci;
  29. -- DATOS DE PRUEBA
  30. INSERT INTO personas(paterno, nombres, materno,
  31. estado, fecha_nacimiento) VALUES
  32. ('Flores','Lucero','Diaz',1 ,'2000-06-05'),
  33. ('Mesa','Flor','Ochoa',4 ,'1990-01-01'),
  34. ('Vela','Mario','Roca',2 ,'1985-12-15'),
  35. ('Ruiz','Pedro','Gamboa',3 ,'2002-02-24')
  36. --VISTA A DETALLE
  37. CREATE VIEW personas_detalle AS
  38. SELECT personas.id id, personas.paterno paterno,
  39. personas.materno materno, personas.nombres nombres,
  40. estado.nombres estado ,personas.foto foto,
  41. personas.fecha_nacimiento fecha_nacimiento
  42. FROM personas INNER JOIN estado ON personas.estado = estado.id


Creando el archivo de configuración

Creamos el documento: config.php
  1. <?php
  2. date_default_timezone_set("America/Lima");
  3. define("DB_HOST", "localhost");
  4. define("DB_USER", "root"); # Usuario root
  5. define("DB_PASSWORD", ""); # Sin contraseña
  6. define("DB_NAME", "blog"); # Nombre de la base de datos
  7. define("DB_PORT", "3306"); # Puerto 3306 - MySQL, 3307 - MariaBD


Creando la conexión y funciones básicas

Existen dos formas, de crear el archivo de conexión:
  • Mediante un archivo simple de conexión
  • Mediante una clase
Y existen dos formas de realizar la conexión:
  • Usando mysqli
  • Usando PDO
En este caso haremos el más sencillo que es un archivo simple y mysqli
Creamos un archivo llamado: biblioteca_mysql.php

  1. <?php
  2. include_once('config.php');
  3. $cnx = '';
  4. /**
  5. * Función para Conectarse a la base de datos
  6. */
  7. function bd_conectar() {
  8. global $cnx;
  9. $cnx = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT);
  10. mysqli_query($cnx, "set names utf8");
  11. }
  12. /**
  13. * Función para desconectarse de la base de datos
  14. */
  15. function bd_desconectar() {
  16. global $cnx;
  17. mysqli_close($cnx);
  18. }
  19. /**
  20. * Función para realizar consultas (SELECT) a la base de datos
  21. */
  22. function bd_consultar($sql) {
  23. global $cnx;
  24. $bolsa = mysqli_query($cnx, $sql);
  25. $salida = array();
  26. if ($bolsa != null) {
  27. while ($row = mysqli_fetch_assoc($bolsa)) {
  28. $salida[] = $row;
  29. }
  30. mysqli_free_result($bolsa);
  31. } else {
  32. $salida = false;
  33. }
  34. unset($row);
  35. return $salida;
  36. }
  37. /**
  38. * Función para ejecuciones INSERT, UPDATE o DELETE a la base de datos
  39. */
  40. function bd_ejecutar($sql) {
  41. global $cnx;
  42. $exito = mysqli_query($cnx, $sql);
  43. if ($exito) {
  44. return true;
  45. } else {
  46. return false;
  47. }
  48. }


Función para cargar la imagen

Creamos un archivo que permite insertar y editar registros: editar_grabar.php


  1. <?php
  2. include_once 'biblioteca_mysql.php';
  3. $id = $_POST['txtid'];
  4. $pat = $_POST['txtpat'];
  5. $mat = $_POST['txtmat'];
  6. $nom = $_POST['txtnom'];
  7. $fec = $_POST['txtcum'];
  8. $est = $_POST['cboestado'];
  9. $existFoto = false;
  10. if (file_exists($_FILES['foto']['tmp_name'])) {
  11. #Extraemos el contenido de la imagen
  12. $fp = fopen($_FILES['foto']['tmp_name'], 'rb');
  13. $imagen = fread($fp, filesize($_FILES['foto']['tmp_name']));
  14. $imagen = addslashes($imagen);
  15. fclose($fp); #Cerramos imagen
  16. $existFoto = true;
  17. }
  18. if ($_POST['txtid'] == '') {
  19. $sql = "INSERT INTO personas (paterno, materno, nombres, estado";
  20. $sql .= ($existFoto) ? ", foto" : "";
  21. $sql .= ", fecha_nacimiento) values('$pat','$mat','$nom','$est'";
  22. $sql .= ($existFoto) ? ", '$imagen'" : "";
  23. $sql .= ",'$fec ')";
  24. } else {
  25. $id = $_POST['txtid'];
  26. $sql = "UPDATE personas SET paterno = '$pat', materno = '$mat',";
  27. $sql .= " nombres = '$nom', fecha_nacimiento = '$fec', ";
  28. $sql .= "estado = $est";
  29. $sql .= ($existFoto) ? ", foto = '$imagen'" : "";
  30. $sql .= " WHERE id = $id";
  31. }
  32. unset($existFoto);
  33. bd_conectar();
  34. if (bd_ejecutar($sql)) {
  35. bd_desconectar();
  36. header('location: index.php');
  37. } else {
  38. echo "Error al procesar el registro:<br/>";
  39. echo '<a href="index.php">Regresar</a>';
  40. bd_desconectar();
  41. }


Función para mostrar la imagen

Agregamos la función bd_ejecutar al archivo llamado: mostrar_imagen.php


  1. <?php
  2. include_once 'biblioteca_mysql.php';
  3. $id=$_GET['id'];
  4. bd_conectar();
  5. $sql="SELECT foto FROM personas WHERE id='$id'";
  6. $rpta=mysqli_query($cnx,$sql);
  7. $pers=mysqli_fetch_assoc($rpta);
  8. header("Content-type: image/png");
  9. echo $pers['foto'];
  10. bd_desconectar();


Creando una interfaz (Tablas y formularios)

Creamos un archivo llamado: personas.php
Aquí llamamos al documento PHP que contiene las funciones de conexión y para ejecutar sentencias SQL, recorriendola mediante un FOREACH en una tabla.

  1. <?php
  2. include_once 'biblioteca_mysql.php';
  3. $sql = "SELECT * FROM personas_detalle";
  4. bd_conectar();
  5. $registros = bd_consultar($sql);
  6. bd_desconectar();
  7. ?>
  8. <!DOCTYPE html>
  9. <html>
  10. <head>
  11. <title>Reporte de inscritos</title>
  12. </head>
  13. <body><br/><br/>
  14. <a class="boton" href="nuevo_formulario.html">Nuevo Registro</a><br/>
  15. <table>
  16. <caption><b>Reporte de Personas</b></caption>
  17. <thead>
  18. <th>ID</th>
  19. <th>APELLIDO PATERNO</th>
  20. <th>APELLIDO MATERNO</th>
  21. <th>NOMBRES</th>
  22. <th>CUMPLEAÑOS</th>
  23. <th>ESTADO CIVIL</th>
  24. <th>FOTO</th>
  25. <th>ACCIONES</th>
  26. </thead>
  27. <tbody>
  28. <?php foreach ($registros as $persona) {?>
  29. <tr>
  30. <td><?= $persona['id'] ?></td>
  31. <td><?= $persona['paterno'] ?></td>
  32. <td><?= $persona['materno'] ?></td>
  33. <td><?= $persona['nombres'] ?></td>
  34. <td><?= $persona['fecha_nacimiento'] ?></td>
  35. <td><?= strtoupper($persona['estado']) ?></td>
  36. <td>
  37. <img
  38. src="mostrar_imagen.php?id=<?= $persona['id']; ?>"
  39. height="50"/>
  40. </td>
  41. <td>
  42. <a href="editar_formulario.php?id=<?= $persona['id'] ?>">
  43. EDITAR
  44. </a>
  45. <a href="borrar.php?id=<?= $persona['id'] ?>"
  46. onclick="return confirm('¿Deseas borrar el registro?')">
  47. BORRAR
  48. </a>
  49. </td>
  50. </tr>
  51. <?php } ?>
  52. </tbody>
  53. </table><br/>
  54. </body>
  55. </html>


Creamos un archivo llamado: editar_formulario.php

  1. <?php
  2. include_once 'biblioteca_mysql.php';
  3. $rotulo = "AGREGAR";
  4. if (isset($_GET['id'])){
  5. $id = $_GET['id'];$sql = "SELECT * FROM personas WHERE id = $id";
  6. $rotulo = "MODIFICAR";
  7. bd_conectar();
  8. $registros = bd_consultar($sql);
  9. $persona = $registros[0];
  10. unset($registros);
  11. bd_desconectar();
  12. }else {
  13. $persona = null;
  14. }
  15. ?>
  16. <!DOCTYPE html>
  17. <html>
  18. <head>
  19. <title><?= $rotulo ?> PERSONA</title>
  20. </head>
  21. <body>
  22. <form enctype="multipart/form-data" name="formulario_grabar_editar"
  23. method="POST" action="editar_grabar.php">
  24. <input type="text" name="txtid" value="<?= $persona['id']?>"
  25. hidden="hidden" readonly="readonly"><br/>
  26. Apellido paterno:<br/>
  27. <input type="text" name="txtpat" value="<?= $persona['paterno']?>"
  28. placeholder="Ingrese su apellido paterno" maxlength="25"><br/>
  29. <br/>Apellido materno:<br/>
  30. <input type="text" name="txtmat" value="<?= $persona['materno']?>"
  31. placeholder="Ingrese su apellido materno" maxlength="25"><br/>
  32. <br/>Nombres:<br/>
  33. <input type="text" name="txtnom" value="<?= $persona['nombres']?>"
  34. placeholder="Ingrese sus nombres" maxlength="25"><br/>
  35. <br/>Fecha de nacimiento:<br/>
  36. <input type="date" name="txtcum" value="<?= $persona['fecha_nacimiento']?>"
  37. placeholder="Ingrese su fecha de nac."><br/>
  38. <br/>Seleccionar estado civil:
  39. <select name="cboestado">
  40. <option>Seleccione</option>
  41. <option value="1" <?=$persona['estado']==1 ? 'selected' : '' ?> >
  42. Soltero</option>
  43. <option value="2" <?=$persona['estado']==2 ? 'selected' : '' ?> >
  44. Casado</option>
  45. <option value="3" <?=$persona['estado']==3 ? 'selected' : '' ?> >
  46. Divorciado</option>
  47. <option value="4" <?=$persona['estado']==4 ? 'selected' : '' ?> >
  48. Viudo</option>
  49. </select><br/>
  50. Foto:<input type="file" name="foto">
  51. <br/><br/>
  52. <input type="submit" name="btnGrabar" value="<?= $rotulo ?>">
  53. </form>
  54. </body>
  55. </html>



Resultado

Página Index

Lo ideal es subir las imágenes al servidor y almacenar la URL en la base de datos, pero en caso de imágenes de alto valor o muy "sensibles". Se puede optar por almacenar dicha imagen u otro tipo de archivo como un instalador en la base de datos.


No hay comentarios:

Publicar un comentario