PHP-FPM/mod_php auf Shared Hosting erbt keine shell-exportierten Umgebungsvariablen wie der lokale Dev-Server. app/bootstrap.php laedt jetzt optional env.local.php (nicht eingecheckt, siehe env.local.example.php als Vorlage) und setzt die Variablen per putenv(), bevor irgendein app_env()/getenv()-Aufruf passiert. Greift jetzt auch fuer CLI-Skripte (migrate.php, grant-platform-admin.php) ueber scripts/dev-db.php.
111 lines
2.7 KiB
PHP
111 lines
2.7 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/../app/bootstrap.php';
|
|
|
|
function dev_required_env(string $name): string
|
|
{
|
|
$value = getenv($name);
|
|
if ($value === false || trim($value) === '') {
|
|
fwrite(STDERR, "Missing environment variable: {$name}\n");
|
|
exit(1);
|
|
}
|
|
|
|
return $value;
|
|
}
|
|
|
|
function dev_pdo(): PDO
|
|
{
|
|
$dsn = sprintf(
|
|
'mysql:host=%s;port=%s;dbname=%s;charset=utf8mb4',
|
|
dev_required_env('DB_HOST'),
|
|
getenv('DB_PORT') ?: '3306',
|
|
dev_required_env('DB_NAME')
|
|
);
|
|
|
|
return new PDO($dsn, dev_required_env('DB_USER'), dev_required_env('DB_PASS'), [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
|
PDO::ATTR_EMULATE_PREPARES => true,
|
|
]);
|
|
}
|
|
|
|
function dev_apply_schema(PDO $pdo): void
|
|
{
|
|
dev_apply_migrations($pdo);
|
|
}
|
|
|
|
function dev_migrations_dir(): string
|
|
{
|
|
return __DIR__ . '/../database/migrations';
|
|
}
|
|
|
|
function dev_ensure_migration_table(PDO $pdo): void
|
|
{
|
|
$pdo->exec(
|
|
'CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
version VARCHAR(255) PRIMARY KEY,
|
|
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @return array<string, true>
|
|
*/
|
|
function dev_applied_migrations(PDO $pdo): array
|
|
{
|
|
dev_ensure_migration_table($pdo);
|
|
|
|
$applied = [];
|
|
$stmt = $pdo->query('SELECT version FROM schema_migrations ORDER BY version');
|
|
foreach ($stmt->fetchAll(PDO::FETCH_COLUMN) as $version) {
|
|
$applied[(string)$version] = true;
|
|
}
|
|
|
|
return $applied;
|
|
}
|
|
|
|
/**
|
|
* @return list<string> Applied migration filenames.
|
|
*/
|
|
function dev_apply_migrations(PDO $pdo): array
|
|
{
|
|
$dir = dev_migrations_dir();
|
|
$files = glob($dir . '/*.sql');
|
|
if ($files === false || $files === []) {
|
|
fwrite(STDERR, "No migration files found in {$dir}.\n");
|
|
exit(1);
|
|
}
|
|
|
|
sort($files, SORT_STRING);
|
|
$applied = dev_applied_migrations($pdo);
|
|
$newlyApplied = [];
|
|
$insert = $pdo->prepare('INSERT INTO schema_migrations (version) VALUES (?)');
|
|
|
|
foreach ($files as $file) {
|
|
$version = basename($file);
|
|
if (isset($applied[$version])) {
|
|
continue;
|
|
}
|
|
|
|
$sql = file_get_contents($file);
|
|
if ($sql === false) {
|
|
fwrite(STDERR, "Could not read migration file {$version}.\n");
|
|
exit(1);
|
|
}
|
|
|
|
try {
|
|
$pdo->exec($sql);
|
|
$insert->execute([$version]);
|
|
$newlyApplied[] = $version;
|
|
} catch (Throwable $e) {
|
|
fwrite(STDERR, "Migration {$version} failed: {$e->getMessage()}\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
return $newlyApplied;
|
|
}
|