set_error_handler() ist praktisch, wenn du PHP-Fehler nicht einfach irgendwo verstreut behandeln willst. Stattdessen reagierst du an einer zentralen Stelle auf Warnungen, Notices oder eigene Fehler.
set_error_handler(function (int $severity, string $message, string $file, int $line): bool {
error_log("[$severity] $message in $file:$line");
return true;
});
Warum das nützlich ist:
Du bekommst einheitliches Logging und kannst viele alte Warnungen in saubere Exceptions umwandeln.
set_error_handler(function (int $severity, string $message, string $file, int $line): bool {
throw new ErrorException($message, 0, $severity, $file, $line);
});
Besonders hilfreich bei:
- Legacy-Code
- Bibliotheken mit schwacher Fehlerbehandlung
- Projekten, in denen du Fehler lieber gesammelt als stillschweigend behandeln willst
Wichtig:
Nicht jeder Fehler sollte blind zu einer Exception werden. In produktiven Systemen lohnt sich ein klarer Plan, welche Fehler du hart behandelst und welche nur geloggt werden.
register_shutdown_function() läuft ganz am Ende des Skripts — auch dann, wenn vorher etwas richtig schiefgelaufen ist. Genau deshalb ist die Funktion so wertvoll für Logging und Notfall-Handling.
register_shutdown_function(function (): void {
$error = error_get_last();
if ($error === null) {
return;
}
error_log($error['message'] . ' in ' . $error['file'] . ':' . $error['line']);
});
Warum das nützlich ist:
Du kannst fatale Fehler noch erkennen, bevor der Request komplett verschwindet, und bekommst wenigstens ein sauberes Log.
Typische Einsatzfälle:
- Fehlerprotokollierung
- Cleanup von temporären Dateien
- letzte Benachrichtigung bei kritischen Abbrüchen
Wichtig:
Die Shutdown-Funktion ist keine Wunderwaffe. Wenn schon ein fataler Fehler passiert ist, ist dein Spielraum begrenzt — aber für Diagnose und Aufräumen oft genau richtig.
Wenn irgendwo eine Exception durchrutscht, ist set_exception_handler() dein letzter sauberer Anlaufpunkt. Genau dafür ist die Funktion stark: Du definierst einmal zentral, was bei einem unbehandelten Fehler passieren soll.
set_exception_handler(function (Throwable $e): void {
error_log($e->__toString());
http_response_code(500);
echo 'Es ist ein Fehler aufgetreten.';
});
Warum das nützlich ist:
Du brauchst nicht überall denselben Fallback-Code und bekommst trotzdem einheitliches Logging sowie eine kontrollierte Antwort an den Browser.
Besonders praktisch bei:
- APIs
- kleinen Projekten ohne großes Framework
- Bootstrap-Dateien, die den ganzen Request initialisieren
Wichtig:
Der Handler selbst sollte sehr robust sein. Wenn dort wieder ein Fehler passiert, wird die eigentliche Ursache schnell schwerer nachvollziehbar.
~/.cache auf tmpfs zu legen ist auf Desktop-Systemen oft überraschend nützlich. Genau dort landen Browser-Cache, Thumbnails, Build-Reste und anderer Kram, der nach einem Neustart meist nicht wirklich fehlt.
Gerade Browser schreiben permanent kleine Dateien. Allein dadurch kommen viele unnötige Schreibzugriffe zusammen. Wenn ~/.cache im RAM liegt, ist das schneller erledigt und die SSD wird nicht dauernd mit Wegwerfdateien beschäftigt.
tmpfs /home/USERNAME/.cache tmpfs rw,nosuid,nodev,noatime,uid=1000,gid=1000,mode=700 0 0
Pfad, uid und gid musst du an dein System anpassen.
Natürlich ist tmpfs nicht gratis: Der Platz kommt aus dem RAM und nach einem Neustart ist der Cache weg. Aber genau das ist hier meistens eher ein Vorteil als ein Nachteil.
Meine Faustregel: Wenn genug RAM da ist, lohnt sich tmpfs auf ~/.cache fast immer. Schon allein wegen der Browserdateien.
103 Early Hints ist ein HTTP-Status, mit dem der Server dem Browser schon vor der eigentlichen Response wichtige Hinweise schicken kann, z. B. welche CSS- oder Font-Dateien direkt geladen werden sollen.
HTTP/1.1 103 Early Hints
HTTP/1.1 200 OK
Wo hilft das?
Vor allem bei SSR, langsamen Datenbankabfragen oder generell hohem TTFB. Der Browser kann kritische Assets schon anfordern, während das Backend noch an der finalen HTML-Antwort arbeitet.
Wichtig:
Early Hints bringt vor allem etwas für Assets, die du sehr sicher brauchst. Für wechselnde oder unklare Ressourcen ist der Effekt gering oder du preloadest unnötig.
Mit dem Server-Timing HTTP-Header verschickst du Performance-Metriken direkt an den Browser. Diese tauchen sofort im DevTools unter Network → Timings auf.
Format:
Server-Timing: db;dur=123;desc="Query"
In PHP:
$start = microtime(true);
$duration = (microtime(true) - $start) * 1000;
header("Server-Timing: db;dur=$duration;desc=\"Database\"", true);
Live Demo: https://server-timing-hono.deno.dev/ – öffne DevTools, schau in Network → Timing
Wenn du im Frontend schnell debuggen willst, nutze einen geheimen Hash im User-Agent.
Nur wenn der Hash stimmt, gibt das Backend Debug-Infos aus (z. B. Timing, Cache-Hit/Miss, interne Steps).
$ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
$token = $_ENV['UA_DEBUG_TOKEN'] ?? '';
$debug = $token !== '' && str_contains($ua, 'DevCoreDebug/' . $token);
if ($debug) {
header('X-Debug-Info: ' . json_encode(['dbMs' => 42, 'cache' => 'MISS']));
}
Warum gut:
Du erzeugst keinen Debug-Noise für normale User, siehst direkt im echten Frontend, was passiert, und kannst alles ohne extra UI-Flag aktivieren.
Wichtig:
Das ist kein Security-Feature, sondern nur ein Debug-Schalter; gib keine sensiblen Daten aus und wechsle den Token regelmäßig.