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
-- TABLA ESTADO
CREATE TABLE estado (
id INT NOT NULL AUTO_INCREMENT ,
nombres VARCHAR(100) NOT NULL ,
PRIMARY KEY (id)
)ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_general_ci;
/* DATOS DE INICIO */
INSERT INTO estado(nombres) VALUES
('soltero'),
('casado'),
('divorciado'),
('viudo')
-- TABLA PERSONAS
CREATE TABLE personas (
id INT NOT NULL AUTO_INCREMENT ,
paterno VARCHAR(150) NOT NULL ,
materno VARCHAR(150) NOT NULL ,
nombres VARCHAR(100) NOT NULL ,
estado INT NOT NULL ,
foto MEDIUMBLOB NULL ,
fecha_nacimiento DATE NOT NULL ,
PRIMARY KEY (id), /* CLAVE PRIMARIA */
CONSTRAINT fk_estado /* CLAVE FORÁNEA */
FOREIGN KEY (estado)
REFERENCES estado (id)
ON DELETE NO ACTION
ON UPDATE NO ACTION
)ENGINE = InnoDB CHARSET=utf8 COLLATE utf8_general_ci;
-- DATOS DE PRUEBA
INSERT INTO personas(paterno, nombres, materno,
estado, fecha_nacimiento) VALUES
('Flores','Lucero','Diaz',1 ,'2000-06-05'),
('Mesa','Flor','Ochoa',4 ,'1990-01-01'),
('Vela','Mario','Roca',2 ,'1985-12-15'),
('Ruiz','Pedro','Gamboa',3 ,'2002-02-24')
--VISTA A DETALLE
CREATE VIEW personas_detalle AS
SELECT personas.id id, personas.paterno paterno,
personas.materno materno, personas.nombres nombres,
estado.nombres estado ,personas.foto foto,
personas.fecha_nacimiento fecha_nacimiento
FROM personas INNER JOIN estado ON personas.estado = estado.id
Creando el archivo de configuración
Creamos el documento:
config.php
<?php
date_default_timezone_set("America/Lima");
define("DB_HOST", "localhost");
define("DB_USER", "root"); # Usuario root
define("DB_PASSWORD", ""); # Sin contraseña
define("DB_NAME", "blog"); # Nombre de la base de datos
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:
En este caso haremos el más sencillo que es un archivo simple y mysqli
Creamos un archivo llamado:
biblioteca_mysql.php
<?php
include_once('config.php');
$cnx = '';
/**
* Función para Conectarse a la base de datos
*/
function bd_conectar() {
global $cnx;
$cnx = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME, DB_PORT);
mysqli_query($cnx, "set names utf8");
}
/**
* Función para desconectarse de la base de datos
*/
function bd_desconectar() {
global $cnx;
mysqli_close($cnx);
}
/**
* Función para realizar consultas (SELECT) a la base de datos
*/
function bd_consultar($sql) {
global $cnx;
$bolsa = mysqli_query($cnx, $sql);
$salida = array();
if ($bolsa != null) {
while ($row = mysqli_fetch_assoc($bolsa)) {
$salida[] = $row;
}
mysqli_free_result($bolsa);
} else {
$salida = false;
}
unset($row);
return $salida;
}
/**
* Función para ejecuciones INSERT, UPDATE o DELETE a la base de datos
*/
function bd_ejecutar($sql) {
global $cnx;
$exito = mysqli_query($cnx, $sql);
if ($exito) {
return true;
} else {
return false;
}
}
Función para cargar la imagen
Creamos un archivo que permite insertar y editar registros:
editar_grabar.php
<?php
include_once 'biblioteca_mysql.php';
$id = $_POST['txtid'];
$pat = $_POST['txtpat'];
$mat = $_POST['txtmat'];
$nom = $_POST['txtnom'];
$fec = $_POST['txtcum'];
$est = $_POST['cboestado'];
$existFoto = false;
if (file_exists($_FILES['foto']['tmp_name'])) {
#Extraemos el contenido de la imagen
$fp = fopen($_FILES['foto']['tmp_name'], 'rb');
$imagen = fread($fp, filesize($_FILES['foto']['tmp_name']));
$imagen = addslashes($imagen);
fclose($fp); #Cerramos imagen
$existFoto = true;
}
if ($_POST['txtid'] == '') {
$sql = "INSERT INTO personas (paterno, materno, nombres, estado";
$sql .= ($existFoto) ? ", foto" : "";
$sql .= ", fecha_nacimiento) values('$pat','$mat','$nom','$est'";
$sql .= ($existFoto) ? ", '$imagen'" : "";
$sql .= ",'$fec ')";
} else {
$id = $_POST['txtid'];
$sql = "UPDATE personas SET paterno = '$pat', materno = '$mat',";
$sql .= " nombres = '$nom', fecha_nacimiento = '$fec', ";
$sql .= "estado = $est";
$sql .= ($existFoto) ? ", foto = '$imagen'" : "";
$sql .= " WHERE id = $id";
}
unset($existFoto);
bd_conectar();
if (bd_ejecutar($sql)) {
bd_desconectar();
header('location: index.php');
} else {
echo "Error al procesar el registro:<br/>";
echo '<a href="index.php">Regresar</a>';
bd_desconectar();
}
Función para mostrar la imagen
Agregamos la función bd_ejecutar al archivo llamado:
mostrar_imagen.php
<?php
include_once 'biblioteca_mysql.php';
$id=$_GET['id'];
bd_conectar();
$sql="SELECT foto FROM personas WHERE id='$id'";
$rpta=mysqli_query($cnx,$sql);
$pers=mysqli_fetch_assoc($rpta);
header("Content-type: image/png");
echo $pers['foto'];
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.
<?php
include_once 'biblioteca_mysql.php';
$sql = "SELECT * FROM personas_detalle";
bd_conectar();
$registros = bd_consultar($sql);
bd_desconectar();
?>
<!DOCTYPE html>
<html>
<head>
<title>Reporte de inscritos</title>
</head>
<body><br/><br/>
<a class="boton" href="nuevo_formulario.html">Nuevo Registro</a><br/>
<table>
<caption><b>Reporte de Personas</b></caption>
<thead>
<th>ID</th>
<th>APELLIDO PATERNO</th>
<th>APELLIDO MATERNO</th>
<th>NOMBRES</th>
<th>CUMPLEAÑOS</th>
<th>ESTADO CIVIL</th>
<th>FOTO</th>
<th>ACCIONES</th>
</thead>
<tbody>
<?php foreach ($registros as $persona) {?>
<tr>
<td><?= $persona['id'] ?></td>
<td><?= $persona['paterno'] ?></td>
<td><?= $persona['materno'] ?></td>
<td><?= $persona['nombres'] ?></td>
<td><?= $persona['fecha_nacimiento'] ?></td>
<td><?= strtoupper($persona['estado']) ?></td>
<td>
<img
src="mostrar_imagen.php?id=<?= $persona['id']; ?>"
height="50"/>
</td>
<td>
<a href="editar_formulario.php?id=<?= $persona['id'] ?>">
EDITAR
</a>
<a href="borrar.php?id=<?= $persona['id'] ?>"
onclick="return confirm('¿Deseas borrar el registro?')">
BORRAR
</a>
</td>
</tr>
<?php } ?>
</tbody>
</table><br/>
</body>
</html>
Creamos un archivo llamado:
editar_formulario.php
<?php
include_once 'biblioteca_mysql.php';
$rotulo = "AGREGAR";
if (isset($_GET['id'])){
$id = $_GET['id'];$sql = "SELECT * FROM personas WHERE id = $id";
$rotulo = "MODIFICAR";
bd_conectar();
$registros = bd_consultar($sql);
$persona = $registros[0];
unset($registros);
bd_desconectar();
}else {
$persona = null;
}
?>
<!DOCTYPE html>
<html>
<head>
<title><?= $rotulo ?> PERSONA</title>
</head>
<body>
<form enctype="multipart/form-data" name="formulario_grabar_editar"
method="POST" action="editar_grabar.php">
<input type="text" name="txtid" value="<?= $persona['id']?>"
hidden="hidden" readonly="readonly"><br/>
Apellido paterno:<br/>
<input type="text" name="txtpat" value="<?= $persona['paterno']?>"
placeholder="Ingrese su apellido paterno" maxlength="25"><br/>
<br/>Apellido materno:<br/>
<input type="text" name="txtmat" value="<?= $persona['materno']?>"
placeholder="Ingrese su apellido materno" maxlength="25"><br/>
<br/>Nombres:<br/>
<input type="text" name="txtnom" value="<?= $persona['nombres']?>"
placeholder="Ingrese sus nombres" maxlength="25"><br/>
<br/>Fecha de nacimiento:<br/>
<input type="date" name="txtcum" value="<?= $persona['fecha_nacimiento']?>"
placeholder="Ingrese su fecha de nac."><br/>
<br/>Seleccionar estado civil:
<select name="cboestado">
<option>Seleccione</option>
<option value="1" <?=$persona['estado']==1 ? 'selected' : '' ?> >
Soltero</option>
<option value="2" <?=$persona['estado']==2 ? 'selected' : '' ?> >
Casado</option>
<option value="3" <?=$persona['estado']==3 ? 'selected' : '' ?> >
Divorciado</option>
<option value="4" <?=$persona['estado']==4 ? 'selected' : '' ?> >
Viudo</option>
</select><br/>
Foto:<input type="file" name="foto">
<br/><br/>
<input type="submit" name="btnGrabar" value="<?= $rotulo ?>">
</form>
</body>
</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.