PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; try { $pdo = new PDO($dsn, $db_user, $db_pass, $options); return $pdo; } catch (PDOException $e) { // In a real application, you would log this error and show a generic error page. // For this development environment, we'll just show the error. error_log('Database Connection Error: ' . $e->getMessage()); // Returning null or you could throw an exception. return null; } } /** * Runs database migrations. * It finds all .php files in the migrations directory and runs them in order. * Each migration file should contain a function with the same name as the file (without .php). */ function run_migrations() { $pdo = db(); if (!$pdo) { // Cannot run migrations without a database connection. return; } $migration_dir = __DIR__ . '/migrations'; if (!is_dir($migration_dir)) { return; // No migrations directory. } $files = glob($migration_dir . '/*.php'); sort($files); // Check if migrations table exists, create if not $pdo->exec("CREATE TABLE IF NOT EXISTS migrations (migration VARCHAR(255) PRIMARY KEY)"); // Get all executed migrations $executed_migrations = $pdo->query("SELECT migration FROM migrations")->fetchAll(PDO::FETCH_COLUMN); foreach ($files as $file) { $migration_name = basename($file, '.php'); if (in_array($migration_name, $executed_migrations)) { continue; // Skip already executed migration } require_once $file; // The function name inside the migration file must match the filename. // e.g., 001_create_agenda_table.php must contain a function named 'migration_001_create_agenda_table' $migration_function_name = 'migration_' . str_replace(['-'], '_', $migration_name); if (function_exists($migration_function_name)) { try { $pdo->beginTransaction(); $migration_function_name($pdo); // Record the migration $stmt = $pdo->prepare("INSERT INTO migrations (migration) VALUES (?)"); $stmt->execute([$migration_name]); $pdo->commit(); } catch (Exception $e) { $pdo->rollBack(); error_log("Migration failed: {$migration_name}. Error: " . $e->getMessage()); // Stop on first failed migration return; } } } }