Code-Review für Legacy-Systeme: worauf es ankommt

Ein Legacy Code Review folgt anderen Regeln als das Review eines frischen Features. Worauf Sie wirklich achten müssen, um Risiken zu finden, ohne funktionierende Logik kaputtzumachen.

Ein System, das seit acht oder zwölf Jahren im Produktivbetrieb läuft, Rechnungen schreibt und Bestellungen verarbeitet, ist kein Sanierungsfall aus Prinzip. Es ist der lebende Beweis, dass die Fachlogik funktioniert. Genau das macht ein Legacy Code Review zu einer eigenen Disziplin: Sie bewerten nicht, ob jemand sauber programmiert hat, sondern ob und wo das System Sie im Ernstfall im Stich lässt. Das ist ein völlig anderer Blickwinkel als beim Review eines frisch geschriebenen Features.

Wer ein altes System mit der Checkliste für Neuentwicklung reviewt, produziert hunderte Findings, die alle richtig und fast alle irrelevant sind. Am Ende steht die Empfehlung "neu schreiben" — meist die teuerste und riskanteste aller Optionen. Ein gutes Review kommt zu einem nützlicheren Ergebnis: Es trennt das, was wirklich weh tut, von dem, was nur unschön aussieht.

Warum ein Legacy Code Review andere Ziele verfolgt

Bei neuem Code fragen Sie: Ist das gut gebaut? Bei altem Code fragen Sie: Was passiert, wenn ich das anfasse? Der entscheidende Unterschied ist das Risiko der Veränderung. Jede Zeile, die seit Jahren läuft, enthält implizites Wissen — Sonderfälle, Workarounds für längst vergessene Kundenanforderungen, stille Abhängigkeiten. Dieses Wissen steht nirgends dokumentiert. Es steht im Code.

Das Ziel eines Legacy Code Review ist deshalb nicht Schönheit, sondern eine belastbare Antwort auf drei Fragen: Wo sind die konkreten Gefahren (Sicherheit, Datenverlust)? Wo ist eine geplante Änderung riskant, und warum? Und wo lohnt sich eine Investition am meisten? Alles andere ist nachrangig.

Sicherheit zuerst — hier wird es unangenehm konkret

Alte PHP-Anwendungen tragen fast immer eine Sicherheitsschuld mit sich, und die ist selten harmlos. Das sind die Stellen, die ich zuerst suche:

  • SQL-Injection durch String-Konkatenation. Direkt zusammengebaute Queries ("SELECT ... WHERE id = " . $_GET['id']) statt Prepared Statements. In gewachsenen Systemen finden Sie oft beides parallel — die neuen Teile mit PDO, die alten ohne.
  • Fehlendes Output-Escaping. Direkte Ausgaben ohne htmlspecialchars() sind XSS-Einfallstore. In alten Templates ist das die Regel, nicht die Ausnahme.
  • Veraltete Passwort-Hashes. MD5 oder SHA1 ohne Salt, teils sogar Klartext. Hier reicht ein einziger Fund, um das Review zur Chefsache zu machen.
  • Bekannte Schwachstellen in Abhängigkeiten. Ein composer audit gegen eine alte composer.lock ist oft ernüchternd. Framework-Versionen ohne Sicherheitssupport (etwa altes Symfony oder Laravel) gehören auf die erste Seite des Berichts.

Sicherheit ist der einzige Bereich, in dem ich beim Legacy Code Review kompromisslos bin. Ein unschöner Service kostet Wartungszeit. Eine offene Injection kostet irgendwann die Firma.

Fachlogik respektieren, den Code drumherum kritisieren

Und hier liegt der Kern meiner Haltung: Das Problem ist fast nie die Fachlogik. Die Berechnung der Staffelpreise, die Provisionslogik, die Regeln für den Versand — das läuft, oft seit Jahren, korrekt. Kaputt ist meist die Verpackung: eine 2000-Zeilen-Methode, in der die eigentliche Regel unter Datenbankzugriffen, HTML-Ausgabe und Fehlerbehandlung begraben liegt.

Ein gutes Review markiert genau diesen Unterschied. Statt "diese Klasse ist ein Chaos" schreibe ich: "Die Preislogik in den Zeilen X bis Y ist wertvoll und getestet-durch-Praxis; sie ist nur eng mit der Datenbankschicht verwoben. Ziel: herauslösen, nicht neu erfinden." Das ist der Punkt, an dem ein Review vom Nörgeln zur Strategie wird. Sie schützen das funktionierende Wissen und greifen nur die Struktur an.

Praktisch heißt das: Achten Sie auf die Grenzen zwischen Fachlogik und Infrastruktur. Wo vermischt sich Domänenwissen mit mysqli-Aufrufen, mit echo, mit $_SESSION? Diese Vermischung ist das eigentliche Änderungsrisiko — nicht die Logik selbst.

Testbarkeit und Änderungsrisiko bewerten

Die vielleicht wichtigste Frage beim Legacy Code Review lautet: Kann ich diese Stelle mit einem Test absichern, bevor ich sie ändere? Legacy-Code ist oft deshalb gefährlich, weil er sich nicht isoliert testen lässt — globaler Zustand, statische Aufrufe, Datenbankzugriffe mitten in der Logik, keine Dependency Injection.

Bewerten Sie jede kritische Änderung entlang dieser Achse. Ein Bereich mit klaren Ein- und Ausgaben lässt sich mit einem Charakterisierungstest umschließen und dann gefahrlos umbauen. Ein Bereich, der ohne komplettes System nicht anläuft, ist teuer und riskant — hier muss zuerst eine Naht (ein Seam) geschaffen werden, bevor überhaupt an Refactoring zu denken ist. Michael Feathers' Ansatz aus "Working Effectively with Legacy Code" ist hier nach wie vor die beste Referenz.

Was ich bewusst ignoriere

Ein Legacy Code Review, das alles anstreicht, ist wertlos, weil es niemand priorisieren kann. Diese Dinge notiere ich höchstens am Rande:

  • Formatierung, Namenskonventionen, Coding-Style — wenn es keinen Schmerz verursacht, ist es kosmetisch.
  • "Nicht mehr moderne" Muster, die aber stabil funktionieren und selten angefasst werden.
  • Fehlende Tests in Code, der nachweislich seit Jahren stabil läuft und nicht geändert werden soll.

Die Kunst liegt im Weglassen. Ein Bericht mit fünfzehn echten Risiken ist wertvoller als einer mit dreihundert Anmerkungen, in denen die fünfzehn untergehen.

Ein pragmatischer Ablauf

Wenn ich ein System zum ersten Mal reviewe, gehe ich in dieser Reihenfolge vor: erst Sicherheit und Abhängigkeiten (die harten Risiken), dann die Bereiche, die als Nächstes geändert werden sollen (das aktuelle Änderungsrisiko), dann die zentralen Fachlogik-Inseln (das schützenswerte Wissen), und zuletzt der Rest. Diese Reihenfolge stellt sicher, dass die knappe Aufmerksamkeit dort landet, wo sie den größten Unterschied macht.

Der ehrliche Praxis-Tipp zum Schluss

Widerstehen Sie dem Reflex, ein System nach dem ersten Blick als "Müll" abzustempeln. Formulieren Sie jedes Finding als Frage nach Konsequenz und Risiko, nicht nach Geschmack: Was passiert, wenn wir das nicht anfassen? Was passiert, wenn wir es tun? Ein Review, das diese zwei Fragen für jede kritische Stelle ehrlich beantwortet, ist mehr wert als jede Sammlung von Best-Practice-Verstößen — und es führt fast immer weg von der teuren Neuentwicklung, hin zu gezielten, bezahlbaren Eingriffen.

Genau bei solchen Reviews und der anschließenden schrittweisen Modernisierung von Legacy-PHP-Systemen unterstützt LegacyWerk, wenn Sie eine zweite, ehrliche Einschätzung brauchen.

Prioritaeten im Legacy Code Review 1. Sicherheit und Abhaengigkeiten harte Risiken 2. Bereiche fuer geplante Aenderungen Aenderungsrisiko 3. Zentrale Fachlogik-Inseln schuetzenswert 4. Der Rest meist kosmetisch abnehmende Dringlichkeit

Ist Ihre PHP-Anwendung noch zu retten?

Im kostenlosen Kurz-Check schauen wir mit Ihnen auf Ihr System und sagen Ihnen ehrlich, was möglich ist, unverbindlich und ohne Verkaufsdruck.

Kurz-Check vereinbaren