'PHP', 'name' => 'PHP-Version', 'value' => PHP_VERSION, 'ok' => version_compare(PHP_VERSION, '8.2.0', '>='), 'hint' => 'Mindestens PHP 8.2 erforderlich.', ]; $results[] = [ 'group' => 'PHP', 'name' => 'Server-API (SAPI)', 'value' => PHP_SAPI, 'ok' => true, 'hint' => '', ]; $extensions = ['pdo', 'pdo_sqlite', 'mbstring', 'openssl', 'tokenizer', 'xml', 'ctype', 'fileinfo', 'dom', 'curl']; foreach ($extensions as $ext) { $results[] = [ 'group' => 'PHP-Extensions', 'name' => $ext, 'value' => extension_loaded($ext) ? 'Geladen' : 'Fehlt', 'ok' => extension_loaded($ext), 'hint' => $ext === 'pdo_sqlite' ? 'Nur fuer SQLite noetig' : '', ]; } // Optional $results[] = [ 'group' => 'PHP-Extensions', 'name' => 'pdo_mysql (optional)', 'value' => extension_loaded('pdo_mysql') ? 'Geladen' : 'Fehlt', 'ok' => true, // optional 'hint' => 'Nur fuer MySQL noetig.', ]; // ─── Dateisystem ───────────────────────────────────────────── $dirs = [ 'storage', 'storage/app', 'storage/framework', 'storage/framework/cache', 'storage/framework/cache/data', 'storage/framework/sessions', 'storage/framework/views', 'storage/logs', 'bootstrap/cache', 'database', ]; foreach ($dirs as $dir) { $full = $basePath . '/' . $dir; $exists = is_dir($full); $writable = $exists && is_writable($full); $perms = $exists ? substr(sprintf('%o', fileperms($full)), -4) : '-'; $owner = $exists ? (function_exists('posix_getpwuid') ? posix_getpwuid(fileowner($full))['name'] ?? fileowner($full) : fileowner($full)) : '-'; $results[] = [ 'group' => 'Verzeichnisse', 'name' => $dir . '/', 'value' => ($exists ? 'Existiert' : 'FEHLT') . ' | ' . ($writable ? 'Beschreibbar' : 'NICHT beschreibbar') . ' | ' . $perms . ' | Owner: ' . $owner, 'ok' => $writable, 'hint' => !$writable ? 'Berechtigungen auf 775 setzen' : '', ]; } // ─── Dateien ───────────────────────────────────────────────── $files = [ '.env' => 'Konfigurationsdatei (wird automatisch erstellt)', '.env.example' => 'Vorlage fuer .env', 'vendor/autoload.php' => 'Composer-Abhaengigkeiten', 'bootstrap/app.php' => 'Laravel-Bootstrap', 'storage/installed' => 'Installations-Marker (fehlt bei Erstinstallation)', ]; foreach ($files as $file => $desc) { $full = $basePath . '/' . $file; $exists = file_exists($full); // storage/installed SOLL bei Erstinstallation fehlen $isOptional = ($file === 'storage/installed' || $file === '.env'); $results[] = [ 'group' => 'Dateien', 'name' => $file, 'value' => $exists ? 'Vorhanden' : 'Fehlt', 'ok' => $exists || $isOptional, 'hint' => $desc, ]; } // ─── Webserver ─────────────────────────────────────────────── $results[] = [ 'group' => 'Webserver', 'name' => 'Server-Software', 'value' => $_SERVER['SERVER_SOFTWARE'] ?? 'Unbekannt', 'ok' => true, 'hint' => '', ]; $results[] = [ 'group' => 'Webserver', 'name' => 'Document Root', 'value' => $_SERVER['DOCUMENT_ROOT'] ?? 'Unbekannt', 'ok' => true, 'hint' => 'Muss auf den public/-Ordner zeigen.', ]; $results[] = [ 'group' => 'Webserver', 'name' => 'Script-Pfad', 'value' => __FILE__, 'ok' => true, 'hint' => '', ]; $results[] = [ 'group' => 'Webserver', 'name' => 'PHP-User', 'value' => function_exists('posix_getpwuid') ? (posix_getpwuid(posix_geteuid())['name'] ?? posix_geteuid()) : get_current_user(), 'ok' => true, 'hint' => 'Unter diesem User laeuft PHP.', ]; $results[] = [ 'group' => 'Webserver', 'name' => 'mod_rewrite', 'value' => (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules())) ? 'Aktiv' : 'Nicht pruefbar / Nicht aktiv', 'ok' => true, // Can't reliably detect 'hint' => 'Wird fuer saubere URLs benoetigt.', ]; // ─── index.php Datei-Check ─────────────────────────────────── $indexPath = __DIR__ . '/index.php'; $indexExists = file_exists($indexPath); $indexSize = $indexExists ? filesize($indexPath) : 0; $indexMtime = $indexExists ? date('Y-m-d H:i:s', filemtime($indexPath)) : '-'; $indexFirstLines = $indexExists ? implode("\n", array_slice(file($indexPath), 0, 10)) : ''; $hasTryCatch = $indexExists && strpos(file_get_contents($indexPath), 'Throwable') !== false; $results[] = [ 'group' => 'index.php Pruefung', 'name' => 'Dateigroesse', 'value' => $indexSize . ' Bytes', 'ok' => $indexSize > 1000, 'hint' => 'Neue index.php sollte ueber 5000 Bytes sein.', ]; $results[] = [ 'group' => 'index.php Pruefung', 'name' => 'Letzte Aenderung', 'value' => $indexMtime, 'ok' => true, 'hint' => '', ]; $results[] = [ 'group' => 'index.php Pruefung', 'name' => 'try-catch vorhanden', 'value' => $hasTryCatch ? 'Ja' : 'Nein (ALTE VERSION!)', 'ok' => $hasTryCatch, 'hint' => 'Bitte die aktuelle index.php erneut hochladen.', ]; // ─── Laravel Boot-Test ─────────────────────────────────────── $bootSteps = []; $bootError = null; // Schritt 1: Autoloader laden try { require_once __DIR__ . '/../vendor/autoload.php'; $bootSteps[] = ['name' => 'vendor/autoload.php laden', 'ok' => true, 'error' => '']; } catch (\Throwable $e) { $bootSteps[] = ['name' => 'vendor/autoload.php laden', 'ok' => false, 'error' => $e->getMessage()]; $bootError = $e; } // Schritt 2: Bootstrap laden (nur wenn Schritt 1 ok) if (!$bootError) { try { $app = require_once __DIR__ . '/../bootstrap/app.php'; $bootSteps[] = ['name' => 'bootstrap/app.php laden', 'ok' => true, 'error' => '']; } catch (\Throwable $e) { $bootSteps[] = ['name' => 'bootstrap/app.php laden', 'ok' => false, 'error' => $e->getMessage()]; $bootError = $e; } } // Schritt 3: Kernel erstellen (nur wenn Schritt 2 ok) if (!$bootError && isset($app)) { try { $kernel = $app->make(\Illuminate\Contracts\Http\Kernel::class); $bootSteps[] = ['name' => 'HTTP-Kernel erstellen', 'ok' => true, 'error' => '']; } catch (\Throwable $e) { $bootSteps[] = ['name' => 'HTTP-Kernel erstellen', 'ok' => false, 'error' => $e->getMessage()]; $bootError = $e; } } // Schritt 4: Request-Handling simulieren (nur wenn Schritt 3 ok) if (!$bootError && isset($app)) { try { // Simuliere einen GET / Request $testRequest = \Illuminate\Http\Request::create('/', 'GET'); $response = $app->make(\Illuminate\Contracts\Http\Kernel::class)->handle($testRequest); $statusCode = $response->getStatusCode(); $isRedirect = $statusCode >= 300 && $statusCode < 400; $redirectTo = $isRedirect ? $response->headers->get('Location', '') : ''; $bootSteps[] = [ 'name' => 'Request-Handling (GET /)', 'ok' => true, 'error' => 'Status ' . $statusCode . ($isRedirect ? ' → Redirect nach ' . $redirectTo : ''), ]; } catch (\Throwable $e) { $bootSteps[] = ['name' => 'Request-Handling (GET /)', 'ok' => false, 'error' => $e->getMessage()]; $bootError = $e; } } // Schritt 5: Auch /install testen (dort laeuft die eigentliche Seite) if (!$bootError && isset($app)) { try { // Log leeren, damit wir nur den Fehler von diesem Request sehen $logFile = __DIR__ . '/../storage/logs/laravel.log'; @file_put_contents($logFile, ''); // Debug aktivieren, damit die Exception geloggt wird config(['app.debug' => true]); $installRequest = \Illuminate\Http\Request::create('/install', 'GET'); $installResponse = $app->make(\Illuminate\Contracts\Http\Kernel::class)->handle($installRequest); $installStatus = $installResponse->getStatusCode(); if ($installStatus >= 500) { // Fehler aus dem Log auslesen $logContent = file_exists($logFile) ? file_get_contents($logFile) : ''; // Nur die erste Fehlermeldung extrahieren (bis zur ersten Leerzeile) $logLines = explode("\n", $logContent); $errorMsg = ''; foreach ($logLines as $line) { if (strlen($errorMsg) > 1500) break; $errorMsg .= $line . "\n"; } $errorMsg = trim($errorMsg) ?: '(kein Log-Eintrag gefunden)'; $bootSteps[] = [ 'name' => 'Request-Handling (GET /install)', 'ok' => false, 'error' => 'Status ' . $installStatus . ' — Fehler aus laravel.log: ' . $errorMsg, ]; } else { $bootSteps[] = [ 'name' => 'Request-Handling (GET /install)', 'ok' => true, 'error' => 'Status ' . $installStatus, ]; } } catch (\Throwable $e) { $bootSteps[] = ['name' => 'Request-Handling (GET /install)', 'ok' => false, 'error' => $e->getMessage()]; $bootError = $e; } } // ─── OPcache ───────────────────────────────────────────────── $opcacheEnabled = function_exists('opcache_get_status') && opcache_get_status() !== false; $results[] = [ 'group' => 'OPcache', 'name' => 'OPcache aktiv', 'value' => $opcacheEnabled ? 'Ja' : 'Nein', 'ok' => true, 'hint' => '', ]; if ($opcacheEnabled) { $status = opcache_get_status(); $results[] = [ 'group' => 'OPcache', 'name' => 'validate_timestamps', 'value' => ini_get('opcache.validate_timestamps') ? 'Ja' : 'Nein (gefaehrlich!)', 'ok' => (bool) ini_get('opcache.validate_timestamps'), 'hint' => 'Ohne validate_timestamps werden Dateiupdates nicht erkannt.', ]; // OPcache fuer index.php invalidieren $indexInvalidated = opcache_invalidate(__DIR__ . '/index.php', true); $results[] = [ 'group' => 'OPcache', 'name' => 'index.php Cache invalidiert', 'value' => $indexInvalidated ? 'Ja (erfolgreich)' : 'Nein / nicht noetig', 'ok' => true, 'hint' => '', ]; } foreach ($bootSteps as $step) { $results[] = [ 'group' => 'Laravel Boot-Test', 'name' => $step['name'], 'value' => $step['ok'] ? 'OK' : 'FEHLER: ' . $step['error'], 'ok' => $step['ok'], 'hint' => $step['error'], ]; } if ($bootError) { $results[] = [ 'group' => 'Laravel Boot-Test', 'name' => 'Stack-Trace', 'value' => $bootError->getFile() . ':' . $bootError->getLine(), 'ok' => false, 'hint' => $bootError->getTraceAsString(), ]; } // ─── Zusammenfassung ───────────────────────────────────────── $allOk = true; foreach ($results as $r) { if (!$r['ok']) { $allOk = false; break; } } // ─── HTML-Ausgabe ──────────────────────────────────────────── ?>
Handball WebApp — Systemcheck
| ✓ ✗ | ||
→ |
||
Diese Datei nach erfolgreicher Installation loeschen (check.php).