PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci", ]; try { $pdo = new PDO($dsn, env('DB_USER', 'root'), env('DB_PASS', ''), $options); } catch (PDOException $e) { if (APP_DEBUG) { die('Error de conexión: ' . $e->getMessage()); } else { die('Error de conexión a la base de datos. Contacte al administrador.'); } } } return $pdo; } // ── Inicialización de sesión ────────────────────────────────────────────────── function iniciarSesion(): void { if (session_status() === PHP_SESSION_NONE) { session_name(SESSION_NAME); session_set_cookie_params([ 'lifetime' => 0, 'path' => '/', 'secure' => isset($_SERVER['HTTPS']), 'httponly' => true, 'samesite' => 'Strict', ]); session_start(); } // Regenerar ID de sesión periódicamente if (!isset($_SESSION['_last_regen'])) { session_regenerate_id(true); $_SESSION['_last_regen'] = time(); } elseif (time() - $_SESSION['_last_regen'] > 300) { session_regenerate_id(true); $_SESSION['_last_regen'] = time(); } } // ── CSRF ────────────────────────────────────────────────────────────────────── function csrfToken(): string { iniciarSesion(); if (empty($_SESSION[CSRF_TOKEN_NAME])) { $_SESSION[CSRF_TOKEN_NAME] = bin2hex(random_bytes(32)); } return $_SESSION[CSRF_TOKEN_NAME]; } function csrfField(): string { return ''; } function verificarCsrf(): void { $token = $_POST[CSRF_TOKEN_NAME] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? ''; if (!hash_equals($_SESSION[CSRF_TOKEN_NAME] ?? '', $token)) { http_response_code(403); die(json_encode(['error' => 'Token CSRF inválido.'])); } } // ── Sanitización ────────────────────────────────────────────────────────────── function clean(mixed $value): string { return htmlspecialchars(trim((string)$value), ENT_QUOTES, 'UTF-8'); } function redirect(string $url): never { header("Location: $url"); exit(); } function jsonResponse(mixed $data, int $code = 200): never { http_response_code($code); header('Content-Type: application/json; charset=utf-8'); echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); exit(); }