Refactoring von Legacy-Code in PHP: Wie man Chaos in Ordnung verwandelt
Jeder PHP-Entwickler stößt früher oder später auf Legacy-Code – alte, schlecht dokumentierte und oft nicht funktionierende Projekte. Anstatt alles von Grund auf neu zu schreiben (was riskant und teuer ist), ermöglicht ein durchdachtes Refactoring, den Code zu verbessern, ohne Geschäftsprozesse zu unterbrechen. In diesem Artikel schauen wir uns an, wie man Legacy-PHP-Projekte sicher refactored und dabei ihre Funktionsfähigkeit erhält.
1. Bewertung und Vorbereitung: Wo beginnt man mit dem Refactoring von Legacy-Code
Bevor man den Code anfasst, muss man seinen aktuellen Zustand verstehen. Überspringt man diesen Schritt, riskiert man, alles zu zerstören.
- Erstellen Sie ein Backup – einen vollständigen Datenbank-Dump und die Projektdateien.
- Führen Sie ein Audit durch – finden Sie alle Einstiegspunkte, Abhängigkeiten und "Black Boxes". Verwenden Sie
grep, um nachinclude,require,evalundmysql_*-Funktionen zu suchen. - Richten Sie die Umgebung ein – erstellen Sie eine lokale Kopie des Projekts (Docker, Vagrant oder XAMPP).
- Fügen Sie Logging hinzu –
error_logund Monitoring helfen, Fehler nach Änderungen zu verfolgen.
Beispiel für ein einfaches Audit über die Konsole:
# Suche nach veralteten mysql-Funktionengrep -rn "mysql_query\\|mysql_connect\\|mysql_fetch" /path/to/legacy/project/Wichtig: Wenn das Projekt keine Tests hat, wird Refactoring zu einem russischen Roulette. Decken Sie zuerst die kritische Logik mit Tests ab (auch wenn es nur manuelle, in einem Dokument festgehaltene Szenarien sind).
2. Refactoring-Strategie: Kleine Schritte für große Veränderungen
Die beste Strategie für Legacy ist die schrittweise Verbesserung. Versuchen Sie nicht, das gesamte Projekt an einem Wochenende umzuschreiben. Verwenden Sie den Ansatz der "Pfadfinderregel": Hinterlasse den Code sauberer, als du ihn vorgefunden hast.
2.1. Isolieren Sie Änderungen
Jede Änderung sollte minimal und atomar sein. Beispiel: Umbenennen einer Variable in einer Datei, dann Auslagern von doppeltem Code in eine Funktion.
<?php// Vor dem Refactoring (Legacy)$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];$result = mysql_query($sql);
// Danach: Zumindest escapen$id = (int)$_GET['id'];$sql = "SELECT * FROM users WHERE id = $id";$result = mysqli_query($link, $sql);?>2.2. Nutzen Sie Automatisierungswerkzeuge
- PHPStan – statische Analyse, findet Fehler ohne Codeausführung.
- Rector – automatisches Refactoring (PSR-12, Ersetzung veralteter Funktionen).
- PHP CodeSniffer – Überprüfung des Codestils.
- PHPUnit – Modultests.
Beispiel für die Ausführung von Rector zum Ersetzen von mysql_* durch mysqli_*:
vendor/bin/rector process src/ --set mysql-to-mysqli3. Konkrete Refactoring-Techniken für PHP-Code
3.1. Ersetzen von "Spaghetti-Code" durch OOP
Legacy-Code wird oft als eine einzige riesige Datei mit gemischtem HTML und PHP geschrieben. Trennen Sie die Logik in Klassen und Funktionen.
<?php// Schlecht: Code durcheinander$user = getUser($_GET['id']);echo "<h1>Hallo, " . $user['name'] . "</h1>";if ($_POST['action'] === 'save') { saveUser($_POST);}
// Gut: Trennung der Verantwortlichkeitenclass UserController { public function show(int $id): void { $user = $this->userRepository->find($id); $this->render('profile', ['user' => $user]); }}?>3.2. Entfernen von "totem" Code
Nicht verwendete Funktionen, Kommentare, auskommentierte Blöcke – all das erzeugt Rauschen. Entfernen Sie sie ohne Mitleid, aber überprüfen Sie mit git log, ob der Code nicht doch woanders verwendet wird.
// Suche nach nicht verwendeten Funktionen (erfordert PHPStan)vendo