Subida de Ficheros y Validación de Formularios en PHP: Implementación Práctica

Informática y Telecomunicaciones5,4 KB

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

Descargar

PDF Word HTML