Subida de Ficheros y Validación de Formularios en PHP: Implementación Práctica
Subida de Ficheros y Procesamiento de Formularios en PHP
A continuación se presenta la implementación para la gestión, validación y almacenamiento de noticias con ficheros adjuntos (imágenes) mediante PHP y un formulario HTML con codificación multipart/form-data.
Código Completo: Formulario y Procesamiento
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8" />
<title>Subida de ficheros</title>
</head>
<body>
<?php
if (isset($_POST['enviar'])) {
?>
<h2>Subida de ficheros. Resultados del formulario</h2>
<h3>Resultado de la inserción de nueva noticia</h3>
<?php
$titulo = $_POST['titulo'];
$texto = $_POST['texto'];
$categoria = $_POST['categoria'];
$errores = "";
// Validación de campos obligatorios
if (trim($titulo) == "") {
$errores .= "<li>Se requiere el título de la noticia</li>\n";
}
if (trim($texto) == "") {
$errores .= "<li>Se requiere el texto de la noticia</li>\n";
}
$copiarFichero = false;
// Verificación y subida del fichero de imagen
if (is_uploaded_file($_FILES['imagen']['tmp_name'])) {
$nombreDirectorio = "img/";
$nombreFichero = $_FILES['imagen']['name'];
$copiarFichero = true;
$nombreCompleto = $nombreDirectorio . $nombreFichero;
if (is_file($nombreCompleto)) {
$idUnico = time();
$nombreFichero = $idUnico . "-" . $nombreFichero;
}
} else if ($_FILES['imagen']['error'] == UPLOAD_ERR_FORM_SIZE) {
$maxsize = $_POST['MAX_FILE_SIZE'];
$errores .= "<li>El tamaño del fichero supera el límite permitido ($maxsize bytes)</li>\n";
} else if ($_FILES['imagen']['name'] == "") {
$nombreFichero = '';
} else {
$errores .= "<li>No se ha podido subir el fichero</li>\n";
}
// Renderizado del resultado según validación
if ($errores != "") {
print("<p>No se ha podido realizar la inserción debido a los siguientes errores:</p>\n");
print("<ul>\n");
print($errores);
print("</ul>\n");
print("<p>[ <a href='javascript:history.back()'>Volver</a> ]</p>\n");
} else {
print("<p>La noticia ha sido recibida correctamente:</p>\n");
print("<ul>\n");
print("<li><strong>Título:</strong> $titulo</li>\n");
print("<li><strong>Texto:</strong> $texto</li>\n");
print("<li><strong>Categoría:</strong> $categoria</li>\n");
if ($copiarFichero) {
print("<li><strong>Imagen:</strong> <a target='_blank' href='" . $nombreDirectorio . $nombreFichero . "'>" . $nombreFichero . "</a></li>\n");
} else {
print("<li><strong>Imagen:</strong> (no hay)</li>\n");
}
print("</ul>\n");
print("<p>[ <a href='noticias.php'>Insertar otra noticia</a> ]</p>\n");
}
} else {
?>
<h2>Subida de ficheros</h2>
<h3>Insertar nueva noticia</h3>
<form action="noticias.php" method="post" enctype="multipart/form-data">
<p>
<label for="titulo">Título: *</label>
<input type="text" id="titulo" name="titulo" size="50" maxlength="50" />
</p>
<p>
<label for="texto">Texto: *</label>
<textarea id="texto" cols="45" rows="5" name="texto"></textarea>
</p>
<p>
<label for="categoria">Categoría:</label>
<select id="categoria" name="categoria">
<option value="prom" selected="selected">Promociones</option>
<option value="ofer">Ofertas</option>
<option value="cost">Costas</option>
</select>
</p>
<p>
<label for="imagen">Imagen:</label>
<input type="hidden" name="MAX_FILE_SIZE" value="102400" />
<input type="file" id="imagen" name="imagen" />
</p>
<p>
<input type="submit" name="enviar" value="Insertar noticia" />
</p>
</form>
<p><small><strong>NOTA:</strong> Los datos marcados con (*) deben ser rellenados obligatoriamente.</small></p>
<?php
}
?>
</body>
</html>Puntos Clave del Flujo de Trabajo
- Atributo
enctype="multipart/form-data": Obligatorio en la etiqueta<form>para permitir el envío binario de ficheros. - Directiva
MAX_FILE_SIZE: Campo oculto que especifica en bytes el tamaño máximo permitido por el formulario (en este caso, 102.400 bytes o 100 KB). - Función
is_uploaded_file(): Asegura que el archivo temporal proviene realmente de una petición HTTP POST legítima antes de proceder a su almacenamiento. - Prevención de colisiones: Si ya existe un fichero con el mismo nombre en la carpeta de destino, se le antepone una marca de tiempo con
time()para crear un identificador único. - Validación exhaustiva: Se filtran campos en blanco con
trim()y se gestionan posibles incidencias de tamaño conUPLOAD_ERR_FORM_SIZE.