CODEDOCU.de – PHP

PHP: gängige Probleme und Lösungen aus dem Alltag

Lesedauer: ca. 21 Minuten

PHP ist nicht glamourös, aber es ist überall. Formulare, kleine Tools, Import-Skripte, WordPress, einfache APIs, Cronjobs. Und genau weil PHP so häufig „einfach mitläuft“, sind die Probleme oft besonders nervig. Plötzlich kommt ein Fehler 500 und du siehst nichts. Eine Warnung erscheint erst nach einem Update. Ein Redirect klappt nicht, weil „Headers already sent“. Ein Script funktioniert lokal, aber auf dem Server nicht wegen Rechten oder Pfaden. Und wenn du Pech hast, passiert das alles in dem Moment, wo du eigentlich nur schnell etwas fixen wolltest.

Diese Seite sammelt typische PHP Fehlerbilder und deren Lösungen. Nicht als riesiger Programmierkurs, sondern als praktische Checkliste: Was bedeutet die Meldung, warum passiert das, wie löst du es sauber. Wenn du akut einen Fehler hast, spring zu dem Abschnitt, der am ehesten passt. Wenn du langfristig weniger Stress willst, lies auch den Teil zu Debugging und Logs. Der spart dir am meisten Zeit.

Erstmal Ruhe reinbringen

Lesedauer: ca. 1 Minute

Wenn PHP „kaputt“ wirkt, ist es in vielen Fällen nicht kaputt, sondern nur stumm. Der wichtigste Schritt ist: finde das Error Log, prüfe den Zeitpunkt, und lies die erste echte Fehlermeldung. Alles danach ist oft nur Folge.

Fehler 500: Internal Server Error

Lesedauer: ca. 7 Minuten

Ein Fehler 500 ist der unfreundlichste Klassiker. Du bekommst nur eine generische Meldung und denkst: super, was jetzt. Ein 500 kann viele Ursachen haben, aber die grobe Richtung ist fast immer: PHP hat einen fatalen Fehler, der Server findet eine Datei nicht, Rechte passen nicht, oder eine Konfiguration (z.B. .htaccess) ist falsch. Auf Shared Hosting ist es extra nervig, weil du manchmal nicht alles siehst.

Pragmatischer Ablauf: Prüfe zuerst, ob es wirklich PHP ist. Wenn du eine statische HTML Datei im gleichen Ordner hast, lädt die? Wenn ja, ist es eher PHP oder Rewrite. Dann schau ins Error Log. Je nach Hosting liegt es in einem Log-Verzeichnis oder in einem Panel. Wenn du keinen Zugriff hast, hilft oft ein kurzer Blick in die Serververwaltung. Ohne Log ist alles Raten.

Typische Ursachen:

  • Syntaxfehler: ein fehlendes Semikolon oder eine Klammer
  • Fatal error wegen fehlender Funktion oder Klasse
  • Falsche PHP Version: Code nutzt Features, die die Version nicht kann
  • Fehlende Extension: z.B. mbstring, curl, gd
  • Memory Limit: Script frisst zu viel RAM
  • .htaccess Fehler: ungültige Direktive oder Loop

Wenn du das Log hast, lies die erste „Fatal error“ Zeile. Häufig steht dort Datei und Zeile. Das ist fast immer der Einstieg. Wenn die Zeile auf eine include/require zeigt, prüfe ob die Datei existiert und ob der Pfad stimmt. Relative Pfade sind auf Servern oft anders als lokal, weil das Working Directory anders sein kann. Ein Tipp ist, Pfade konsequent über __DIR__ zu bauen, damit includes stabil sind.

Parse error: syntax error

Lesedauer: ca. 5 Minuten

Parse errors sind eigentlich die dankbarsten Fehler, weil sie klar sind: PHP kann den Code nicht lesen. Häufige Gründe sind fehlende Semikolons, vergessene Klammern, falsch geschlossene Anführungszeichen oder ein Copy-Paste, bei dem ein typografisches Anführungszeichen reingerutscht ist.

Wenn du die Meldung „unexpected T_STRING“ oder so bekommst, ist das meistens ein Folgefehler. Der eigentliche Fehler ist ein paar Zeilen davor. Beispiel: du hast ein Anführungszeichen nicht geschlossen, dann interpretiert PHP die nächsten Zeilen als Teil des Strings. Der Fehler wird dann später gemeldet, aber die Ursache ist früher.

Praktischer Weg: Geh in die gemeldete Zeile, schau ein paar Zeilen drüber, prüfe Klammern und Strings. Wenn du einen Editor mit Syntax-Highlighting hast, fällt es oft sofort auf, weil plötzlich der Rest des Dokuments „als String“ eingefärbt ist.

Undefined index / Undefined array key

Lesedauer: ca. 7 Minuten

Das ist ein Dauerbrenner, besonders bei Formularen und GET/POST Parametern. Früher wurde das oft als Notice abgetan, heute ist es je nach PHP Version strenger oder zumindest sichtbarer. Bedeutet: du greifst auf einen Array-Key zu, der nicht existiert. Klassisch: $_GET["id"], aber id wurde gar nicht mitgegeben.

Warum passiert das so oft? Weil man im Code annimmt, dass ein Parameter immer da ist. In der Realität kann aber jemand die URL ohne Parameter aufrufen, ein Formular kann leer abgeschickt werden, oder ein Bot ruft Dinge auf, die du nie gedacht hast. Dann knallt es.

Saubere Lösung: Vor dem Zugriff prüfen. Du kannst z.B. mit isset arbeiten, oder einen Default setzen. Der wichtigste Punkt ist aber: nicht blind vertrauen. Wenn du mit externen Inputs arbeitest, musst du immer davon ausgehen, dass etwas fehlt oder falsch ist.

Auch wichtig: nicht nur „wegdrücken“. Viele packen dann @ vor Variablen oder schalten Fehler aus. Das macht die Seite zwar leise, aber du baust dir Unsicherheit ein. Besser: prüfe und setze Defaults. Dann bleibt dein Code stabil.

Headers already sent

Lesedauer: ca. 8 Minuten

„Cannot modify header information – headers already sent“ ist so ein Klassiker, der immer im falschen Moment kommt. Der Grund ist simpel: HTTP Header müssen gesendet werden, bevor Output kommt. Wenn du also irgendwo schon etwas ausgegeben hast (auch nur ein Leerzeichen), dann kannst du später keinen Header mehr senden, also keine Umleitung und keine Cookie-Setzung.

Was zählt als Output? Alles, was wirklich an den Browser geht: echo, print, HTML außerhalb von PHP-Tags, aber auch unsichtbare Dinge wie BOM (Byte Order Mark) am Anfang der Datei oder Leerzeichen nach dem schließenden PHP-Tag. Gerade dieses „Leerzeichen nach ?>“ ist eine häufige Ursache, weshalb viele PHP Dateien am Ende gar kein ?> haben. Das wirkt ungewohnt, ist aber eine bewährte Praxis, um genau diesen Fehler zu vermeiden.

Wenn du den Fehler hast, steht oft „output started at ...“ mit Datei und Zeile. Das ist dein Einstieg. Geh dahin und such nach Output. Oft ist es nicht dort, wo du den header() aufrufst, sondern früher. Wenn du Templates nutzt, kann es irgendwo im Include sein.

Pragmatische Fixes:

  • Kein Leerzeichen vor <?php oder nach dem schließenden Tag
  • Schließendes ?> am Ende von reinen PHP Dateien weglassen
  • header() Aufrufe möglichst früh machen, bevor HTML kommt
  • Output Buffering nur als Notlösung nutzen, nicht als Standard

Memory exhausted / Allowed memory size exhausted

Lesedauer: ca. 6 Minuten

Wenn PHP meldet, dass das Memory Limit überschritten wurde, ist es fast immer ein Script, das zu viel in den Speicher lädt. Große Dateien lesen, riesige Arrays bauen, Endlosschleifen, Bilder verarbeiten, oder ein ungebremster Import. Auch WordPress kann das triggern, wenn Plugins viel machen.

Du hast zwei Möglichkeiten: Limit erhöhen oder Script optimieren. Limit erhöhen ist schnell, aber manchmal nur ein Pflaster. Optimieren heißt: nicht alles auf einmal laden. Bei Dateien: zeilenweise lesen statt file() auf alles. Bei Datenbanken: paginieren. Bei Bildern: Größen reduzieren. Bei Schleifen: prüfen, ob du wirklich abbrichst.

Wenn es ein einmaliger Import ist, kann ein höheres Limit ok sein. Wenn es im Live-Betrieb passiert, ist es ein echtes Problem. Dann solltest du den Speicherverbrauch an der Wurzel reduzieren. Sonst kommt es wieder.

Maximum execution time exceeded

Lesedauer: ca. 6 Minuten

Ähnlich nervig: ein Script läuft zu lange. Das passiert bei Imports, Bildverarbeitung, großen API Calls, oder wenn du versehentlich in einer Schleife zu viel machst. PHP hat ein Zeitlimit, damit nicht ein Request den Server ewig blockiert.

Auch hier: entweder Limit erhöhen oder Arbeit aufteilen. Für große Aufgaben ist es oft besser, sie in kleinere Schritte zu zerlegen. Beispiel: statt 10.000 Datensätze in einem Request, mach 500 pro Request. Oder nutze Cronjobs. Oder baue einen Fortschrittsmechanismus. Das ist zwar mehr Aufwand, aber dafür stabil.

Wenn du nur kurz debuggen willst, kannst du das Limit temporär erhöhen. Aber dauerhaft solltest du überlegen, ob du die Arbeit asynchron machen musst. Sonst ist das nur eine tickende Zeitbombe.

Dateirechte: Permission denied

Lesedauer: ca. 6 Minuten

„Permission denied“ ist ein Hinweis, dass der PHP Prozess keine Rechte hat, eine Datei zu lesen oder zu schreiben. Das passiert häufig bei Uploads, Logs, Cache-Ordnern oder wenn du Dateien per FTP hochlädst und sie dem falschen Benutzer gehören.

Wichtig ist hier das Verständnis: Auf dem Server läuft PHP als ein bestimmter User. Wenn dieser User keine Schreibrechte hat, geht es nicht. Und es ist nicht nur „chmod 777“. Das ist oft keine gute Idee, weil du damit zu viele Rechte gibst. Besser ist, Ordner sauber zu konfigurieren und Besitzer korrekt zu setzen, damit das System stabil bleibt.

Ein typischer Fall: Du hast einen Ordner uploads, PHP soll dort schreiben. Dann braucht der Ordner Schreibrechte für den PHP User. Wenn du WordPress nutzt, sieht man das oft bei Plugin-Installationen oder Bild-Uploads.

Datei-Uploads: warum Uploads scheitern

Lesedauer: ca. 7 Minuten

Uploads wirken simpel, sind aber an mehrere Limits gebunden. Wenn ein Upload nicht klappt, kann das an der PHP Konfiguration liegen: upload_max_filesize, post_max_size, max_file_uploads, max_execution_time, memory_limit. Wenn post_max_size kleiner ist als upload_max_filesize, ist es trotzdem kaputt. Diese Werte müssen logisch zusammenpassen.

Ein weiterer Punkt ist das Formular: Du brauchst enctype="multipart/form-data". Wenn das fehlt, kommt keine Datei an. Auch der Name des File-Inputs muss stimmen. Und serverseitig musst du in $_FILES schauen, nicht in $_POST.

Wenn ein Upload nicht ankommt, prüfe zuerst, ob überhaupt ein Request mit Datei rausgeht. Dann prüfe serverseitig, ob $_FILES gefüllt ist. Und wenn ja, schau dir den error Code an. PHP liefert für Uploads einen Fehlercode, der dir sagt, ob es z.B. zu groß war oder abgebrochen wurde.

Sessions: warum Login „vergisst“

Lesedauer: ca. 6 Minuten

Sessions sind ein Klassiker bei Logins und kleinen Admin-Tools. Wenn Sessions nicht funktionieren, ist es oft ein Cookie-Thema oder ein Header-Problem. Sessions brauchen Cookies, und Cookies brauchen Header. Wenn du also Output hast, bevor session_start() kommt, kann es schief gehen. Auch hier gilt: session_start() früh aufrufen, bevor HTML kommt.

Außerdem kann es sein, dass der Server Sessions nicht speichern kann, weil der Session-Save-Path nicht schreibbar ist. Dann verhält es sich so, als wären Sessions „instabil“. In Logs sieht man das oft.

Auch Domain- und HTTPS-Themen spielen rein. Wenn Cookies falsch gesetzt werden, z.B. ohne secure Flag oder mit falschem Pfad, können sie auf manchen Seiten fehlen. Dann wirkt es, als würde der Login manchmal gehen, manchmal nicht.

JSON: warum JSON kaputt zurückkommt

Lesedauer: ca. 6 Minuten

Wenn du eine kleine API baust oder AJAX nutzt, ist JSON ein typisches Thema. Häufigster Fehler: du willst JSON ausgeben, aber davor oder danach kommt HTML, ein Warning, oder ein Leerzeichen. Dann ist der JSON-Output kaputt und der Client kann es nicht parsen.

Sauberer Weg: Setze den Content-Type passend, gib nur JSON aus, und beende das Script danach. Außerdem: Wenn Fehler auftreten, gib trotzdem konsistentes JSON zurück oder logge Fehler serverseitig. Wenn du Warnings in den Output lässt, zerstören sie das Format.

Auch Encoding spielt rein. JSON erwartet UTF-8. Wenn du Daten in einer anderen Kodierung hast, kann json_encode scheitern oder komische Zeichen liefern. Dann musst du die Daten vorher normalisieren.

Datenbank-Basics: typische Fehlerbilder

Lesedauer: ca. 7 Minuten

Auch ohne tiefen DB-Kurs gibt es ein paar Klassiker: falsche Zugangsdaten, falscher Host, fehlende Rechte, oder ein Query ist syntaktisch falsch. Oft ist es auch „falsche Zeichencodierung“ in der DB, was wieder zu Umlaut-Problemen führt.

Wenn du DB Fehler hast, ist das wichtigste: Fehler nicht im Output verstecken. Logge sie. Und nutze vorbereitetes Statement, wo es sinnvoll ist. Das hilft nicht nur bei Sicherheit, sondern auch bei Stabilität. Viele DB-Probleme kommen durch unsaubere Inputs.

Wenn eine Seite plötzlich langsam wird, ist oft ein Query schuld, der zu viel lädt. Dann hilft: Limit setzen, paginieren, Index prüfen. Das ist schon tiefer, aber die Idee ist simpel: nicht alles auf einmal.

Sicherheit: die typischen Anfänger-Fallen

Lesedauer: ca. 7 Minuten

Auch wenn du „nur ein kleines Script“ baust: Sicherheit ist schnell relevant, weil es öffentlich erreichbar ist. Die häufigsten Fallen sind: ungeprüfte Inputs, direktes Einfügen von GET/POST in SQL, und Ausgabe ohne Escaping. Das führt zu SQL Injection oder XSS.

Du musst dafür kein Security-Pro werden. Ein paar Grundregeln reichen schon: nie direkt Inputs in SQL, sondern prepared Statements. Bei Output in HTML: Text escapen. Bei File-Uploads: Dateityp prüfen und nicht einfach Dateien ausführbar speichern. Und keine sensiblen Fehler im Browser anzeigen, sondern loggen.

Ein weiterer Punkt: Pfad-Traversal. Wenn du per Parameter Dateinamen annimmst, kann jemand versuchen, "../" zu nutzen. Dann liest du plötzlich falsche Dateien. Also: Inputs whitelist-basiert prüfen. Nicht „alles erlauben und hoffen“.

Debugging: so gehst du sauber vor

Lesedauer: ca. 8 Minuten

PHP Debugging ist am Anfang frustig, weil es oft „nur 500“ zeigt. Darum ist der Ablauf wichtig. Erst Logs. Dann reproduzieren. Dann den Fehler eingrenzen. Und nicht 20 Dinge gleichzeitig ändern. Sonst weißt du nicht, was geholfen hat.

Ein pragmatischer Debugging-Ablauf:

  1. Fehlerzeitpunkt merken (Minute reicht)
  2. Error Log öffnen und die erste relevante Meldung lesen
  3. Datei und Zeile prüfen, vorherige Zeilen mit anschauen
  4. Wenn includes: Pfade prüfen, existiert die Datei wirklich
  5. Wenn es nach Konfiguration riecht: PHP Version und Extensions prüfen
  6. Wenn Output/Redirect: nach Output vor header/session_start suchen
  7. Fix testen, dann erst weiter optimieren

Wenn du lokal testest und es am Server anders ist, sind oft Versionen der Grund. PHP 7 vs 8 kann Unterschiede bringen. Auch error_reporting und display_errors unterscheiden sich. Lokal siehst du alles, am Server nicht. Dann wirkt es wie „es geht lokal, aber nicht online“. Lösung: Versionen anpassen oder Code kompatibel machen.

Was fast immer hilft

Lesedauer: ca. 1 Minute

Wenn du nichts siehst: Logs. Wenn du Redirect/Session-Probleme hast: Output prüfen. Wenn du Random-Warnings nach Updates hast: PHP Version und Deprecated-Meldungen prüfen. Das sind die drei größten Hebel.

FAQ zu typischen PHP Fehlern

Lesedauer: ca. 2 Minuten

FAQ

Warum bekomme ich nur einen Fehler 500 ohne Details

Weil die Fehlerausgabe oft deaktiviert ist. Du brauchst das Error Log vom Server. Dort steht meist Datei und Zeile des fatalen Fehlers.

Warum kommt „Headers already sent“

Weil vor dem header() oder vor dem Setzen von Cookies schon Output gesendet wurde. Das kann auch ein Leerzeichen oder ein BOM am Anfang der Datei sein.

Warum bekomme ich „Undefined index“

Weil du auf einen Parameter oder Array-Key zugreifst, der nicht gesetzt ist. Prüfe mit isset oder setze einen Default, statt blind zuzugreifen.

Status: PHP Bereich Hinweis: Seite lädt ohne Login System: ok