Fix wizard : migrations via Artisan::call() pour éviter l'héritage d'env pgsql

Cause racine : public/index.php charge le .env auto-créé (pgsql) et appelle
putenv('DB_CONNECTION=pgsql'). Les sous-processus exec() héritent cet env OS.
phpdotenv en mode immutable refuse d'écraser une variable déjà définie →
le nouveau .env mysql est ignoré, la migration tente une connexion pgsql.

Fix : reconfiguration de la connexion BDD en mémoire via config() + DB::purge()
puis exécution des migrations via Artisan::call() dans le processus courant.
Plus aucun subprocess pour les migrations → aucun héritage d'env parasite.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-04 22:19:50 +02:00
parent 56dbd8a0bf
commit 9225abc804
+39 -7
View File
@@ -3,6 +3,8 @@
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use PDO;
use PDOException;
@@ -145,17 +147,47 @@ class SetupController extends Controller
if (! $ok) $success = false;
}
// 2b. Purge du cache de config pour forcer la lecture du nouveau .env
// (un bootstrap/cache/config.php résiduel sinon l'emporte sur le .env réécrit)
// 2b. Reconfiguration de la connexion BDD dans le processus courant.
//
// Problème : public/index.php charge le .env auto-créé (pgsql) au premier boot
// et appelle putenv('DB_CONNECTION=pgsql'). Les sous-processus exec() héritent
// cet env OS. phpdotenv en mode immutable (défaut Laravel) refuse d'écraser une
// variable déjà présente dans l'env → le nouveau .env (mysql) est ignoré par le
// subprocess de migration qui continue à tenter une connexion pgsql.
//
// Solution : exécuter les migrations via Artisan::call() dans le processus courant
// après avoir écrasé la config BDD en mémoire — pas de subprocess, pas d'héritage.
if ($success) {
$this->artisanRun($artisan, 'config:clear');
$connConfig = $dbData['driver'] === 'pgsql'
? ['driver' => 'pgsql', 'host' => $dbData['host'], 'port' => (int) $dbData['port'],
'database' => $dbData['database'], 'username' => $dbData['username'],
'password' => $dbData['password'] ?? '', 'charset' => 'utf8', 'prefix' => '',
'schema' => 'public', 'sslmode' => 'prefer']
: ['driver' => 'mysql', 'host' => $dbData['host'], 'port' => (int) $dbData['port'],
'database' => $dbData['database'], 'username' => $dbData['username'],
'password' => $dbData['password'] ?? '', 'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci', 'prefix' => '', 'strict' => true];
config([
'database.default' => $dbData['driver'],
"database.connections.{$dbData['driver']}" => $connConfig,
]);
DB::purge($dbData['driver']);
}
// 3. Migrations
// 3. Migrations (dans le processus courant, config BDD déjà écrasée ci-dessus)
if ($success) {
[$ok, $out] = $this->artisanRun($artisan, 'migrate --force');
$steps[] = ['ok' => $ok, 'label' => 'Migration de la base de données', 'error' => $ok ? null : $out];
if (! $ok) $success = false;
try {
$exitCode = Artisan::call('migrate', ['--force' => true]);
$out = trim(Artisan::output());
$ok = $exitCode === 0;
$steps[] = ['ok' => $ok, 'label' => 'Migration de la base de données', 'error' => $ok ? null : $out];
if (! $ok) $success = false;
} catch (\Exception $e) {
$steps[] = ['ok' => false, 'label' => 'Migration de la base de données', 'error' => $e->getMessage()];
$success = false;
}
}
// 4. Création du compte administrateur