MVC Master

Módulo 8: El Cofre del Tesoro

Toda tu arquitectura universitaria e inserciones N:M Front y Auth están terminadas. Te regalo la "Armería de Snippets" para resolver contratiempos avanzados (Archivos, JSON, Excel, Slugs y Fechas) que demandan la vida real.

Atención: A tu HTML form SIEMPRE ponle el atributo: <form enctype="multipart/form-data">

if (isset($_FILES['foto_perfil']) && $_FILES['foto_perfil']['error'] === UPLOAD_ERR_OK) {
    
    // Evitar que te suban un virus oculto. Ej: "shell.php"
    $ext = pathinfo($_FILES['foto_perfil']['name'], PATHINFO_EXTENSION);
    $permitidos = ['jpg', 'png', 'jpeg', 'pdf'];

    if (in_array(strtolower($ext), $permitidos)) {
        // Generar hash unico Ej: "h89ad92k-foto.jpg"
        $nuevo_nombre = uniqid() . "-foto." . $ext;
        $destino = "public/uploads/" . $nuevo_nombre;
        
        move_uploaded_file($_FILES['foto_perfil']['tmp_name'], $destino);
        echo "¡Archivo subido exitosamente!";
    } else {
        die("Hack flag. No subir .php maliciosos.");
    }
}

// COMO CREAR API PARA REACT JS, ANDROID.
public function miBackendDevuelveJSON() {
    $lista = (new EstudianteModelo())->all();
    header('Content-Type: application/json'); // MAGIA NATIVA DE HTTP
    echo json_encode($lista); exit; // {"id": 1, "nombre": "pablo" }
}

// ============================================
// COMO CONSUMIR API DE GOBIERNO EN PHP
$json_crudo = file_get_contents("https://pokeapi.co/perro");
$datos_php = json_decode($json_crudo, true); // Devuelve Array Asoc.
echo "Nombre: " . $datos_php['nombre'];

Si tu cliente WAMP te pide Excel con millones de datos, los creadores de PDF colapsan. Usa FPUTCSV.

public function descargarReporte() {
    $estudiantes = (new EstudianteModelo())->all(); 
    
    // MÁGIA: Obliga al navegador a "descargarlo"
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename=Reporte_Estudiantes.csv');
    
    $salida = fopen('php://output', 'w');
    fputcsv($salida, ['ID', 'N° Matrícula', 'Nombre Alumno', 'Email']);
    
    foreach ($estudiantes as $est) {
        // Escribe las filas reales
        fputcsv($salida, [$est->id, $est->matricula, $est->nombre, $est->correo]);
    }
    fclose($salida); exit; 
}

$fecha_db    = "2026-12-31 15:30:00"; // Como llega MySQL Inglés feo
$objetoFecha = new DateTime($fecha_db);

// Latina al Front End Formateada
echo $objetoFecha->format('d/m/Y h:i P');

// Calcular edad usando diference Object
$nacimiento = new DateTime("2000-05-14");
$hoy        = new DateTime("now");
$diferencia = $hoy->diff($nacimiento);
echo "Es mayor de edad. Tiene " . $diferencia->y . " años."; 

// Post-Poner pagos de Matrículas...
$objetoFecha->modify('+30 days');

$costo_matricula = 1500000.50;

// Struct: number_format(datoReal, DecimalesMostrados, 'TipoDecimal', 'MilesTipo');

// Latam, Miami -> $1,500,000.50
echo "$" . number_format($costo_matricula, 2, '.', ',');

// España EUR -> 1.500.000,50 €
echo number_format($costo_matricula, 2, ',', '.') . " €";