diff --git a/install.php b/install.php
index 45b21d3..e5edfef 100644
--- a/install.php
+++ b/install.php
@@ -31,11 +31,11 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$host = $_POST['db_host'] ?? '127.0.0.1';
$name = $_POST['db_name'] ?? 'app_database';
$user = $_POST['db_user'] ?? 'root';
- $pass = $_POST['db_pass'] ?? '';
+ $password = $_POST['db_pass'] ?? '';
// Test connection
try {
- $test_pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8mb4", $user, $pass);
+ $test_pdo = new PDO("mysql:host=$host;dbname=$name;charset=utf8mb4", $user, $password);
$test_pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Generate config file content
@@ -44,16 +44,19 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$content .= "define('DB_HOST', " . var_export($host, true) . ");\n";
$content .= "define('DB_NAME', " . var_export($name, true) . ");\n";
$content .= "define('DB_USER', " . var_export($user, true) . ");\n";
- $content .= "define('DB_PASS', " . var_export($pass, true) . ");\n";
+ $content .= "define('DB_PASS', " . var_export($password, true) . ");\n";
$content .= "\n";
$content .= "if (!function_exists('db')) {\n";
$content .= " function db() {\n";
$content .= " static \$pdo;\n";
$content .= " if (!\$pdo) {\n";
$content .= " try {\n";
- $content .= " \$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASS);\n";
- $content .= " \$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);\n";
- $content .= " \$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);\n";
+ $content .= " \$pdo = new PDO('mysql:host=' . DB_HOST . ';dbname=' . DB_NAME . ';charset=utf8mb4', DB_USER, DB_PASS);
+";
+ $content .= " \$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
+";
+ $content .= " \$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
+";
$content .= " } catch (PDOException \$e) {\n";
$content .= " die('Connection failed: ' . \$e->getMessage());\n";
$content .= " }\n";
@@ -63,7 +66,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$content .= "}\n";
if (file_put_contents($config_file, $content)) {
- header('Location: install.php?step=3');
+ header('Location: ' . $_SERVER['PHP_SELF'] . '?step=3');
exit;
} else {
$error = "Failed to write configuration file to $config_file. Please check permissions.";
@@ -95,9 +98,6 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($sql)) continue;
try {
- // Split SQL into multiple statements if necessary
- // Simple split by semicolon. This might fail on some complex SQL,
- // but usually works for basic migrations.
$statements = array_filter(array_map('trim', explode(';', $sql)));
foreach ($statements as $stmt_sql) {
if (empty($stmt_sql)) continue;
@@ -105,11 +105,10 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$pdo->exec($stmt_sql);
} catch (Throwable $e) {
$msg = $e->getMessage();
- // Check if it's a common "already exists" error which we can safely ignore
if (strpos($msg, 'Duplicate column name') !== false ||
strpos($msg, 'Duplicate key name') !== false ||
strpos($msg, 'Duplicate table') !== false ||
- strpos($msg, 'already exists') !== false) {
+ strpos($msg, 'already exists') !== false || strpos($msg, 'Duplicate key on write or update') !== false || strpos($msg, 'errno: 121') !== false) {
continue;
} else {
throw $e;
@@ -124,7 +123,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if (empty($errors)) {
$success = "Successfully applied $applied migrations.";
- header('Location: install.php?step=4');
+ header('Location: ' . $_SERVER['PHP_SELF'] . '?step=4');
exit;
} else {
$error = "Applied migrations, but some errors occurred: