Tutorial 6: Validando el Archivo Subido en PHP
¡Hola y bienvenido de nuevo!
En esta lección vamos a validar el archivo que el usuario sube a través del formulario. Vamos a verificar que el archivo existe, que no está vacío y vamos a obtener su tipo para procesarlo correctamente con Whisper. Vamos a hacerlo paso a paso.
📋 Contenido del Tutorial
Creando el archivo de inicialización
Incluyendo el archivo en index.php
Verificando el método de la solicitud
Validando que el archivo existe
Obteniendo el tipo de archivo
Mostrando mensajes de error
Código completo
Explicación detallada
Próximos pasos
📁 1. Creando el archivo de inicialización
¿Qué es init.php?
El archivo init.php (inicialización) será el punto de entrada para todas las configuraciones y clases de nuestra aplicación. Lo usaremos para:
Conectar a la base de datos
Incluir todas las clases necesarias
Definir constantes globales
Configurar el entorno
Creando el archivo
Paso 1: En la carpeta backend, crea un nuevo archivo llamado init.php.
whisper/ ├── backend/ │ ├── init.php # ¡Nuevo archivo! │ └── classes/ ├── frontend/ │ ├── css/ │ ├── images/ │ └── js/ └── index.php
Paso 2: Por ahora, deja el archivo vacío o con un comentario:
<?php // Archivo de inicialización de la aplicación // Aquí cargaremos todas las clases y configuraciones ?>
🔗 2. Incluyendo el archivo en index.php
Agregando el include
Al inicio de index.php, justo después de abrir la etiqueta PHP, vamos a incluir nuestro archivo init.php:
<?php include 'backend/init.php'; // El resto del código PHP... ?>
Ubicación correcta
El código debe ir antes de cualquier HTML, al principio del archivo:
<?php include 'backend/init.php'; // Aquí irá toda la lógica PHP ?> <!DOCTYPE html> <html> <head> <!-- ... --> </head>
🔍 3. Verificando el método de la solicitud
¿Qué es el método de solicitud?
Cuando el usuario selecciona un archivo, el formulario se envía mediante el método POST. Necesitamos verificar esto en PHP.
Código para verificar el método POST
<?php include 'backend/init.php'; // Verificar si la solicitud es de tipo POST if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Aquí procesaremos el archivo } ?>
Explicación de $_SERVER['REQUEST_METHOD']
| Valor | Significado |
|---|---|
GET | El formulario se envió mediante GET |
POST | El formulario se envió mediante POST |
PUT | Solicitud PUT |
DELETE | Solicitud DELETE |
📄 4. Validando que el archivo existe
Verificando si el archivo está presente
Primero, verificamos que el archivo exista en la solicitud:
if (isset($_FILES['file'])) { // El archivo está presente en la solicitud }
Verificando que el archivo no esté vacío
Luego, verificamos que el nombre del archivo no esté vacío:
if (!empty($_FILES['file']['name'])) { // El archivo tiene un nombre, por lo tanto existe }
Código completo de validación
<?php include 'backend/init.php'; // Verificar si es una solicitud POST if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Verificar si el archivo está presente en la solicitud if (isset($_FILES['file'])) { // Verificar si el nombre del archivo no está vacío if (!empty($_FILES['file']['name'])) { // Archivo válido, podemos procesarlo $fileType = $_FILES['file']['type']; // ... más validaciones y procesamiento } else { // El archivo está vacío $error = "Por favor selecciona un archivo para convertir a texto"; } } else { // No se encontró el archivo en la solicitud $error = "Por favor selecciona un archivo para convertir a texto"; } } ?>
Estructura de $_FILES
Cuando subes un archivo, PHP crea el arreglo $_FILES con esta estructura:
$_FILES['file'] = [ 'name' => 'video.mp4', // Nombre original del archivo 'type' => 'video/mp4', // Tipo MIME del archivo 'tmp_name' => '/tmp/phpXyZ', // Ubicación temporal en el servidor 'error' => 0, // Código de error (0 = sin errores) 'size' => 1234567 // Tamaño en bytes ];
🏷️ 5. Obteniendo el tipo de archivo
¿Por qué necesitamos el tipo de archivo?
El tipo de archivo nos ayudará a:
Validar que sea un formato soportado (video/audio)
Diferenciar entre video y audio para mostrarlo correctamente
Guardar esta información en la base de datos
Obteniendo el tipo MIME
$fileType = $_FILES['file']['type'];
Ejemplos de tipos MIME
| Archivo | Tipo MIME |
|---|---|
| MP4 | video/mp4 |
| AVI | video/x-msvideo |
| MOV | video/quicktime |
| MP3 | audio/mpeg |
| WAV | audio/wav |
| MKV | video/x-matroska |
Verificando el tipo de archivo (debug)
Podemos usar var_dump() para ver qué tipo de archivo se está subiendo:
var_dump($fileType);
Esto nos mostrará el tipo MIME exacto que está enviando el navegador.
🎨 6. Mostrando mensajes de error
Estructura del HTML para errores
En el HTML, tenemos un div preparado para mostrar errores:
<!-- ERROR DIV --> <?php if(isset($error)): ?> <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"> <strong class="font-bold">Error:</strong> <span class="block sm:inline"><?php echo $error; ?></span> </div> <?php endif; ?>
¿Cómo funciona?
PHP verifica si la variable
$errorestá definidaSi existe, muestra el div con el mensaje de error
El mensaje se muestra en color rojo para llamar la atención
Mensajes de error comunes
// Error: No se seleccionó archivo $error = "Por favor selecciona un archivo para convertir a texto"; // Error: Formato no soportado $error = "Formato de archivo no soportado. Por favor usa MP4, AVI, MOV, MP3 o WAV"; // Error: Archivo demasiado grande $error = "El archivo excede el tamaño máximo permitido (500MB)"; // Error: Error al subir el archivo $error = "Error al subir el archivo. Por favor intenta de nuevo";
💻 7. Código completo
Archivo: backend/init.php
<?php // Archivo de inicialización de la aplicación // Aquí cargaremos todas las clases y configuraciones // Por ahora está vacío, pero lo usaremos más adelante ?>
Archivo: index.php (versión completa)
<?php include 'backend/init.php'; // Inicializar variable de error $error = null; // Verificar si la solicitud es POST if ($_SERVER['REQUEST_METHOD'] === 'POST') { // Verificar si el archivo está presente if (isset($_FILES['file'])) { // Verificar si el archivo no está vacío if (!empty($_FILES['file']['name'])) { // Obtener el tipo MIME del archivo $fileType = $_FILES['file']['type']; // Aquí podemos agregar más validaciones // Por ejemplo: verificar el tamaño, la extensión, etc. // Por ahora, solo mostraremos el tipo para debug // echo "Tipo de archivo: " . $fileType; } else { // El archivo está vacío $error = "Por favor selecciona un archivo para convertir a texto"; } } else { // No se encontró el archivo en la solicitud $error = "Por favor selecciona un archivo para convertir a texto"; } } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>My Whisper Ai - Convert Video/Audio language into written text</title> <!-- ... librerías y estilos ... --> </head> <body> <div class="Wrapper"> <div class="inner-wrapper h-screen flex justify-center p-20"> <div class="h-full border-2 rounded-xl border-gray-700" style="width: 1280px; max-height: 1080px; box-shadow: -20px 20px 0px 0px #74a840,-21px 21px 0px 3px #343333"> <div class="flex h-full flex-col items-center"> <!-- Loader --> <div id="loader" class="hidden flex flex-col text-center flex-1" style="width: 600px;"> <div class="flex items-center flex-col"> <img class="w-40 animate-pulse mt-60" src="frontend/images/loader.gif"/> <span class="animate-pulse">Uploading....</span> </div> </div> <!-- Contenido principal --> <div id="upload" class="flex flex-col text-center mt-40" style="width: 600px;"> <img class="mx-auto my-4" src="frontend/images/banner-img.png" style="width: 300px;"> <h1 class="text-4xl py-2">Welcome to My Whisper</h1> <p class="text-xl"> Whisper is an AI tool that allows you to convert video/audio files into text and also translate the text into your desired language. </p> <label style="width: 200px; box-shadow: -7px 6px 0px 0px; border: 1px solid;" class="cursor-pointer select-none mx-auto my-4 rounded-full text-xl text-gray-600 px-10 py-5 border bg-lime-400" for="file-upload"> Upload File </label> <form id="form" method="post" enctype="multipart/form-data"> <input id="file-upload" class="hidden" type="file" name="file"> </form> <!-- ERROR DIV --> <?php if(isset($error)): ?> <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative"> <strong class="font-bold">Error:</strong> <span class="block sm:inline"><?php echo $error; ?></span> </div> <?php endif; ?> <p>Recently Generated Files: Click <a href="view.php?file=1" class="text-green font-bold text-sm">Here to View</a></p> </div> </div> </div> </div> </div> <!-- JS CODE --> <script> $(document).ready(function() { $("#file-upload").change(function() { if (this.files.length > 0) { $("#loader").removeClass('hidden'); $("#upload").addClass('hidden'); $("#form").submit(); } }); }); </script> </body> </html>
📖 8. Explicación detallada
Estructura del PHP
1. Inclusión del archivo de inicialización
include 'backend/init.php';
Incluye el archivo que contiene todas las configuraciones
Permite centralizar la configuración en un solo lugar
2. Verificación del método POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_SERVERes una variable superglobal de PHPContiene información sobre el servidor y la solicitud
REQUEST_METHODindica el método HTTP usado (GET, POST, etc.)
3. Verificación de existencia del archivo
if (isset($_FILES['file'])) {
$_FILESes una variable superglobal para archivos subidosisset()verifica si la variable existe y no es null
4. Verificación de contenido del archivo
if (!empty($_FILES['file']['name'])) {
empty()verifica si la variable está vacía$_FILES['file']['name']es el nombre original del archivoSi está vacío, significa que no se seleccionó ningún archivo
5. Obtención del tipo de archivo
$fileType = $_FILES['file']['type'];
Almacena el tipo MIME del archivo
Útil para validar formatos soportados
El arreglo $_FILES en detalle
$_FILES['file'] = [ 'name' => 'mi_video.mp4', // Nombre original del archivo 'type' => 'video/mp4', // Tipo MIME 'tmp_name' => '/tmp/phpXyZ', // Ruta temporal en el servidor 'error' => 0, // Código de error 'size' => 1234567 // Tamaño en bytes ];
Validaciones que podemos agregar
// 1. Verificar el tamaño del archivo (máximo 500MB) $maxSize = 500 * 1024 * 1024; // 500 MB en bytes if ($_FILES['file']['size'] > $maxSize) { $error = "El archivo es demasiado grande. Máximo 500MB"; } // 2. Verificar la extensión del archivo $allowedExtensions = ['mp4', 'mkv', 'avi', 'mov', 'mp3', 'wav']; $extension = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)); if (!in_array($extension, $allowedExtensions)) { $error = "Formato de archivo no soportado"; } // 3. Verificar el tipo MIME $allowedTypes = ['video/mp4', 'video/x-msvideo', 'audio/mpeg', 'audio/wav']; if (!in_array($_FILES['file']['type'], $allowedTypes)) { $error = "Tipo de archivo no soportado"; } // 4. Verificar errores de subida if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) { $error = "Error al subir el archivo: " . $_FILES['file']['error']; }
Códigos de error de subida
| Código | Constante | Significado |
|---|---|---|
| 0 | UPLOAD_ERR_OK | No hay errores, archivo subido correctamente |
| 1 | UPLOAD_ERR_INI_SIZE | El archivo excede el tamaño máximo permitido por PHP |
| 2 | UPLOAD_ERR_FORM_SIZE | El archivo excede el tamaño máximo del formulario |
| 3 | UPLOAD_ERR_PARTIAL | El archivo solo se subió parcialmente |
| 4 | UPLOAD_ERR_NO_FILE | No se subió ningún archivo |
| 6 | UPLOAD_ERR_NO_TMP_DIR | Falta la carpeta temporal |
| 7 | UPLOAD_ERR_CANT_WRITE | Error al escribir el archivo en el disco |
| 8 | UPLOAD_ERR_EXTENSION | Una extensión de PHP detuvo la subida |
🔄 9. Flujo completo de la aplicación
Diagrama del flujo
1. Usuario selecciona archivo ↓ 2. JavaScript detecta el cambio ↓ 3. Muestra loader y oculta contenido ↓ 4. Envía el formulario (POST) ↓ 5. PHP recibe la solicitud ↓ 6. Verifica que sea POST ↓ 7. Verifica que exista el archivo ↓ 8. Verifica que no esté vacío ↓ 9. Obtiene el tipo de archivo ↓ 10. [Próxima lección] Procesa con Whisper
Ejemplo de ejecución
Escenario 1: Usuario selecciona un archivo
1. Usuario: Clic en "Upload File" 2. Usuario: Selecciona "video.mp4" 3. JavaScript: Detecta cambio 4. JavaScript: Muestra loader 5. JavaScript: Envía formulario 6. PHP: Recibe POST 7. PHP: Verifica $_FILES['file'] 8. PHP: $fileType = 'video/mp4' 9. PHP: Procesamiento exitoso
Escenario 2: Usuario no selecciona archivo
1. Usuario: Clic en "Upload File" 2. Usuario: Cierra el diálogo sin seleccionar 3. JavaScript: No detecta cambio (no se activa) 4. No ocurre nada (funciona correctamente)
Escenario 3: Usuario selecciona archivo pero ocurre error
1. Usuario: Selecciona "video.xyz" (formato no soportado) 2. JavaScript: Envía formulario 3. PHP: Recibe archivo 4. PHP: Verifica tipo MIME 5. PHP: $fileType = 'application/octet-stream' 6. PHP: [Validación falla] 7. PHP: $error = "Formato no soportado" 8. HTML: Muestra el error en rojo
🧪 10. Probando la validación
Pasos para probar:
Abrir la aplicación:
http://localhost/whisper/
Probar sin seleccionar archivo:
No pasa nada (comportamiento esperado)
Probar seleccionando un archivo válido:
Se muestra el loader
Se envía el formulario
No hay errores (por ahora)
Verificar el tipo de archivo:
Puedes agregar
var_dump($fileType);para ver el tipoEl tipo aparecerá en la página después de subir
Debugging
Si quieres ver el tipo de archivo, puedes agregar esta línea temporalmente:
// Después de obtener $fileType echo "<pre>"; var_dump($fileType); echo "</pre>"; // Esto detendrá la ejecución para mostrar el tipo die();
📌 11. Resumen de conceptos clave
| Concepto | Explicación |
|---|---|
$_SERVER['REQUEST_METHOD'] | Indica el método HTTP usado (GET, POST) |
$_FILES | Arreglo con información de archivos subidos |
isset() | Verifica si una variable existe |
empty() | Verifica si una variable está vacía |
$_FILES['file']['type'] | Tipo MIME del archivo |
include | Incluye y evalúa un archivo PHP |
🎯 12. Próximos pasos
Lo que hemos logrado
✅ Configuración inicial del proyecto
✅ Inclusión del archivo init.php
✅ Validación de la solicitud POST
✅ Verificación de existencia del archivo
✅ Obtención del tipo MIME
✅ Mostrar mensajes de error
Lo que viene en la próxima lección
En la siguiente lección vamos a:
Crear una clase PHP para manejar la subida de archivos
Validar el archivo completamente (tamaño, tipo, extensión)
Mover el archivo a la carpeta de uploads
Preparar el archivo para ser procesado por Whisper
Avance del código de la próxima lección
class FileUploader { private $allowedExtensions = ['mp4', 'mkv', 'avi', 'mov', 'mp3', 'wav']; private $maxSize = 500 * 1024 * 1024; // 500MB private $uploadDir = 'assets/uploads/'; public function validate($file) { // Validar extensión // Validar tamaño // Validar tipo MIME // Devolver true/false } public function upload($file) { // Mover archivo a la carpeta de uploads // Generar nombre único // Devolver la ruta del archivo } }
❓ Preguntas frecuentes
¿Por qué necesitamos include 'backend/init.php'?
Para centralizar todas las configuraciones y clases
Facilita el mantenimiento del código
¿Qué significa $_SERVER['REQUEST_METHOD'] === 'POST'?
Verifica que el formulario se haya enviado usando el método POST
Es una medida de seguridad para procesar solo solicitudes POST
¿Por qué usamos empty($_FILES['file']['name']) y no empty($_FILES['file'])?
$_FILES['file']siempre existe aunque no haya archivo$_FILES['file']['name']está vacío si no hay archivoEs una forma más precisa de verificar
¿Qué es el tipo MIME?
Es un estándar que identifica el formato de un archivo
Ejemplo:
video/mp4indica un archivo MP4Útil para validar que el archivo sea del tipo esperado
¿Cómo puedo ver los errores de PHP?
Puedes usar
error_reporting(E_ALL);al inicio del archivoO revisar los logs de PHP en XAMPP
¡Excelente trabajo! Ahora tienes una validación básica de archivos en PHP. En la próxima lección, crearemos una clase dedicada para manejar la subida y validación de archivos de forma más robusta.
Comentarios
Publicar un comentario