Die Website ist gleich wieder da.
Gerade wird etwas erneuert. Bitte versuche es in ein paar Minuten noch einmal.
' .'This website will be back shortly.
'text/html; charset=UTF-8', 'Retry-After' => '300', 'Cache-Control' => 'no-store', 'X-Robots-Tag' => 'noindex', 'Content-Security-Policy' => "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'; base-uri 'none'", ]; private static ?string $wurzel = null; private static bool $gezeigt = false; /** Einmal ganz am Anfang von public/index.php. */ public static function einschalten(string $wurzel): void { self::$wurzel = $wurzel; register_shutdown_function(static function (): void { $fehler = error_get_last(); if (null === $fehler || !in_array($fehler['type'], self::ABBRUCH, true)) { return; } self::melden(sprintf('PHP-Abbruch: %s in %s:%d', $fehler['message'], $fehler['file'], $fehler['line'])); self::seite(); // Danach soll nichts mehr ausgeben - auch nicht die Fehlerseite des Frameworks, das // sich ebenfalls fürs Herunterfahren angemeldet hat. exit in einer Shutdown-Funktion // beendet die übrigen. exit; }); } /** Eine Ausnahme, die aus dem Framework herausgefallen ist. */ public static function ausnahme(\Throwable $fehler, string $adresse = ''): void { self::melden(self::beschreiben($fehler, $adresse)); self::seite(); } /** Ein Fehler, den das Framework abgefangen und als 500 beantwortet hat - nur protokollieren. */ public static function protokollieren(\Throwable $fehler, string $adresse = ''): void { self::melden(self::beschreiben($fehler, $adresse)); } public static function beschreiben(\Throwable $fehler, string $adresse = ''): string { $zeile = sprintf('%s: %s in %s:%d', $fehler::class, $fehler->getMessage(), $fehler->getFile(), $fehler->getLine()); // Die eigentliche Ursache steckt oft eine Ebene tiefer, etwa das SQLite-Problem unter // einer Doctrine-Ausnahme. for ($tiefer = $fehler->getPrevious(), $n = 0; null !== $tiefer && $n < 3; $tiefer = $tiefer->getPrevious(), ++$n) { $zeile .= sprintf(' | Ursache: %s: %s', $tiefer::class, $tiefer->getMessage()); } return ('' === $adresse ? '' : $adresse.' – ').$zeile; } private static function melden(string $text): void { $wurzel = self::$wurzel ?? dirname(__DIR__, 2); $datei = $wurzel.'/'.self::PROTOKOLL; if (!is_dir(dirname($datei))) { @mkdir(dirname($datei), 0o775, true); } if (is_file($datei) && filesize($datei) > self::GRENZE) { @rename($datei, $datei.'.1'); } // Zeilenumbrüche aus Meldungen würden das Protokoll zerreißen; eine Zeile je Ereignis. $text = str_replace(["\r", "\n"], ' ', $text); @file_put_contents($datei, sprintf("[%s UTC] %s\n", gmdate('Y-m-d H:i:s'), mb_substr($text, 0, 4000)), FILE_APPEND | LOCK_EX); } /** Die Seite für Besucher. Ohne Details, ohne Abhängigkeiten, ohne fremde Quellen. */ private static function seite(): void { if (self::$gezeigt || PHP_SAPI === 'cli') { return; } self::$gezeigt = true; while (ob_get_level() > 0) { @ob_end_clean(); } if (!headers_sent()) { http_response_code(503); foreach (self::KOPFZEILEN as $name => $wert) { header($name.': '.$wert); } } echo self::html(); } /** Die Wartungsseite als Text, auch für den Fehler-Listener im Framework. */ public static function html(): string { return '
' .'Gerade wird etwas erneuert. Bitte versuche es in ein paar Minuten noch einmal.
' .'This website will be back shortly.