From c7408db956c3aa9b56985f5c1ceac95e27081097 Mon Sep 17 00:00:00 2001 From: Niek Rabelink Date: Tue, 8 Sep 2026 14:05:13 +0200 Subject: [PATCH] fix: explicitly check if database and tables already exist before creating --- config/database.php | 194 +++++++++++++++++++++++++------------------- 1 file changed, 109 insertions(+), 85 deletions(-) diff --git a/config/database.php b/config/database.php index 98e3530..2c1ebc0 100644 --- a/config/database.php +++ b/config/database.php @@ -8,111 +8,135 @@ require_once __DIR__ . '/config.php'; function get_db_connection(): PDO { static $pdo = null; - if ($pdo === null) { - // Controleer of de PDO MySQL/MariaDB driver überhaupt aanwezig is in deze PHP installatie - $availableDrivers = PDO::getAvailableDrivers(); - if (!in_array('mysql', $availableDrivers)) { - $driversList = !empty($availableDrivers) ? implode(', ', $availableDrivers) : 'geen'; - die(" -
-
-

- ⚠️ PHP MySQL Driver Ontbreekt (pdo_mysql) -

-

- De PHP-installatie op uw server heeft momenteel de pdo_mysql extensie niet ingeschakeld. Zonder deze driver kan PHP geen verbinding maken met MariaDB. -

-
- Oplossing per servertype: -
    -
  • Ubuntu / Debian:
    sudo apt install php-mysql && sudo systemctl restart apache2 (of php-fpm)
  • -
  • CentOS / RHEL / AlmaLinux:
    sudo dnf install php-mysqlnd && sudo systemctl restart httpd
  • -
  • cPanel / DirectAdmin / Plesk:
    Ga naar Select PHP Version → Extensions en vink pdo_mysql (en nd_pdo_mysql of mysqlnd) aan.
  • -
  • Windows / XAMPP:
    Verwijder de puntkomma ; voor extension=pdo_mysql in uw php.ini en herstart Apache.
  • -
-
-
- PHP Versie: " . PHP_VERSION . " • Momenteel actieve drivers: " . htmlspecialchars($driversList) . " + if ($pdo !== null) { + return $pdo; + } + + // 1. Controleer of de PDO MySQL/MariaDB driver aanwezig is in PHP + $availableDrivers = PDO::getAvailableDrivers(); + if (!in_array('mysql', $availableDrivers)) { + $driversList = !empty($availableDrivers) ? implode(', ', $availableDrivers) : 'geen'; + die(" +
+
+

⚠️ PHP MySQL Driver Ontbreekt (pdo_mysql)

+

De extensie pdo_mysql is niet actief in deze PHP-omgeving.

+
+
+ "); + } + + $options = [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + PDO::ATTR_TIMEOUT => 5, + ]; + if (defined('PDO::MYSQL_ATTR_MULTI_STATEMENTS')) { + $options[PDO::MYSQL_ATTR_MULTI_STATEMENTS] = true; + } + + $dsnWithDb = sprintf( + 'mysql:host=%s;port=%s;dbname=%s;charset=%s', + DB_HOST, + DB_PORT, + DB_NAME, + DB_CHARSET + ); + + // 2. CHECK: Bestaat de database al? + // We proberen eerst direct verbinding te maken met de database. + // Als de database al bestaat, lukt dit direct zonder database-aanmaakrechten te vereisen! + try { + $pdo = new PDO($dsnWithDb, DB_USER, DB_PASS, $options); + + // De database bestaat al! Controleer enkel of de tabellen al aanwezig zijn + ensure_tables_exist($pdo); + return $pdo; + + } catch (PDOException $e) { + // Foutcode 1049 betekent: Database 'DB_NAME' bestaat nog NIET op de MariaDB server + if ($e->getCode() == 1049 || str_contains($e->getMessage(), 'Unknown database')) { + // Probeer de database eenmalig aan te maken indien de gebruiker CREATE rechten heeft + try { + $serverDsn = sprintf('mysql:host=%s;port=%s;charset=%s', DB_HOST, DB_PORT, DB_CHARSET); + $serverPdo = new PDO($serverDsn, DB_USER, DB_PASS, $options); + $serverPdo->exec(sprintf( + 'CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci', + DB_NAME + )); + + // Nu opnieuw verbinden met de nieuw aangemaakte database + $pdo = new PDO($dsnWithDb, DB_USER, DB_PASS, $options); + ensure_tables_exist($pdo); + return $pdo; + + } catch (PDOException $createEx) { + die(" +
+
+

⚠️ Database '" . htmlspecialchars(DB_NAME) . "' bestaat nog niet

+

+ De database " . htmlspecialchars(DB_NAME) . " bestaat nog niet op MariaDB server " . htmlspecialchars(DB_HOST) . " en de gebruiker " . htmlspecialchars(DB_USER) . " heeft geen rechten om automatisch databases aan te maken. +

+

+ Maak de database " . htmlspecialchars(DB_NAME) . " eenmalig aan via phpMyAdmin, HeidiSQL of de MariaDB CLI: +

+ + CREATE DATABASE IF NOT EXISTS `" . htmlspecialchars(DB_NAME) . "` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +
-
- "); - } - - $dsn = sprintf( - 'mysql:host=%s;port=%s;dbname=%s;charset=%s', - DB_HOST, - DB_PORT, - DB_NAME, - DB_CHARSET - ); - - $options = [ - PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, - PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, - PDO::ATTR_EMULATE_PREPARES => false, - PDO::ATTR_TIMEOUT => 5, - ]; - if (defined('PDO::MYSQL_ATTR_MULTI_STATEMENTS')) { - $options[PDO::MYSQL_ATTR_MULTI_STATEMENTS] = true; - } - - try { - $pdo = new PDO($dsn, DB_USER, DB_PASS, $options); - // Zorg ervoor dat tabellen bestaan - ensure_tables_exist($pdo); - } catch (PDOException $e) { - // Als de database zelf nog niet bestaat, probeer deze aan te maken indien gebruiker rechten heeft - if ($e->getCode() == 1049) { - try { - $tempDsn = sprintf('mysql:host=%s;port=%s;charset=%s', DB_HOST, DB_PORT, DB_CHARSET); - $tempPdo = new PDO($tempDsn, DB_USER, DB_PASS, $options); - $tempPdo->exec(sprintf('CREATE DATABASE IF NOT EXISTS `%s` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci', DB_NAME)); - $pdo = new PDO($dsn, DB_USER, DB_PASS, $options); - ensure_tables_exist($pdo); - return $pdo; - } catch (PDOException $ex) { - die("Database verbindingsfout: Kan database '" . htmlspecialchars(DB_NAME) . "' niet aanmaken of vinden op " . htmlspecialchars(DB_HOST) . ". Maak deze handmatig aan in MariaDB."); - } + "); } - die(" -
-

MariaDB Verbindingsfout (" . htmlspecialchars((string)$e->getCode()) . ")

-

" . htmlspecialchars($e->getMessage()) . "

-
+ } + + // Andere verbindingsfout (bijv. verkeerd wachtwoord, poort of host onbereikbaar) + die(" +
+
+

MariaDB Verbindingsfout (" . htmlspecialchars((string)$e->getCode()) . ")

+

" . htmlspecialchars($e->getMessage()) . "

+
Host: " . htmlspecialchars(DB_HOST) . "
Poort: " . htmlspecialchars(DB_PORT) . "
Database: " . htmlspecialchars(DB_NAME) . "
Gebruiker: " . htmlspecialchars(DB_USER) . "
- "); - } +
+ "); } - - return $pdo; } /** - * Zorgt ervoor dat alle tabellen uit schema.sql aanwezig zijn in MariaDB + * Zorgt ervoor dat alle benodigde tabellen uit schema.sql aanwezig zijn in MariaDB + * Voert niets uit als de tabellen al bestaan! */ function ensure_tables_exist(PDO $pdo): void { try { + // Controleer of de hoofdtabel 'users' al bestaat $result = $pdo->query("SHOW TABLES LIKE 'users'"); - if ($result->rowCount() === 0) { - $schemaFile = __DIR__ . '/../schema.sql'; - if (file_exists($schemaFile)) { - $sql = file_get_contents($schemaFile); - // Splits op puntkomma om elk CREATE TABLE statement apart uit te voeren - $statements = array_filter(array_map('trim', explode(';', $sql))); - foreach ($statements as $stmt) { - if (!empty($stmt)) { - $pdo->exec($stmt); - } + if ($result && $result->rowCount() > 0) { + // Tabellen bestaan al! Geen actie nodig. + return; + } + + // Tabellen ontbreken nog: voer schema.sql uit statement voor statement + $schemaFile = __DIR__ . '/../schema.sql'; + if (file_exists($schemaFile)) { + $sql = file_get_contents($schemaFile); + $statements = array_filter(array_map('trim', explode(';', $sql))); + foreach ($statements as $stmt) { + // Verwijder eventuele SQL commentaren aan het begin + $stmtClean = preg_replace('/^--.*$/m', '', $stmt); + $stmtClean = trim($stmtClean); + if (!empty($stmtClean)) { + $pdo->exec($stmtClean); } } } } catch (Exception $e) { - error_log("Fout bij uitvoeren schema.sql: " . $e->getMessage()); + error_log("Fout bij aanmaken tabellen: " . $e->getMessage()); } }