PHP-Code-Refactoring: Wann es nötig ist und wie Sie Ihr Projekt nicht gefährden
\n\nJeder PHP-Entwickler stößt früher oder später auf Code, den man am liebsten komplett neu schreiben würde. Legacy-Projekte in PHP sind voller „magic numbers“, bildschirmfüllender Funktionen und Klassen, die für alles und jeden zuständig sind. Die Finger jucken, Ordnung zu schaffen. Aber lohnt sich das? Und wenn ja – wie führen Sie ein PHP-Refactoring sicher und effektiv durch?
\n\nIn diesem Artikel beleuchten wir, wann ein Refactoring wirklich notwendig ist und wann Sie besser die Finger davon lassen. Sie sehen echte Beispiele für schlechten und guten PHP-Code, erhalten eine Checkliste und lernen, wie Sie aus der Code-Verbesserung keine Katastrophe machen.
\n\nWann ist ein PHP-Refactoring sinnvoll?
\n\nRefactoring bedeutet, die interne Struktur des Codes zu ändern, ohne sein externes Verhalten zu beeinflussen. Klingt einfach, ist aber in der Praxis eine der riskantesten Aufgaben in der Entwicklung. Hier sind Anzeichen, dass Sie über eine Verbesserung Ihres PHP-Codes nachdenken sollten:
\n\n- \n
- Der Code „stinkt“ (Code Smells). Überlange Methoden, Code-Duplizierung, Gottklassen (God objects), unverständliche Variablennamen. \n
- Das Hinzufügen neuer Funktionen wird zur Qual. Wenn jeder Pull-Request drei andere Stellen kaputt macht, ist das ein Alarmzeichen. \n
- Sie verstehen eine Woche später nicht mehr, was Ihre Methode tut. Schlechter Code ist Code, der zu jeder Zeile einen Kommentar benötigt. \n
- Das Single-Responsibility-Prinzip (SRP) wird verletzt. Eine Klasse „UserManager“, die Benutzer anlegt, E-Mails versendet und Berichte generiert, ist ein klassischer Kandidat für ein Refactoring. \n
Es gibt jedoch Situationen, in denen ein PHP-Refactoring mehr schaden als nutzen kann:
\n- \n
- Der Abgabetermin ist morgen, aber der Code funktioniert. \n
- Es gibt keine Tests. Ohne Tests ist jede Änderung russisches Roulette. \n
- Der Code wurde schnell für einen Prototypen geschrieben, der morgen weggeworfen wird. \n
Regeln für sicheres Refactoring
\n\nBevor Sie mit dem PHP-Refactoring beginnen, merken Sie sich drei eiserne Regeln:
\n\n- \n
- Schreiben Sie Tests für den Code. Zumindest Integrationstests. Wenn es keine Tests gibt, schreiben Sie sie für die kritischen Bereiche. \n
- Refactoren Sie in kleinen Schritten. Eine Methode nach der anderen. Pushen – prüfen – weitermachen. \n
- Vermischen Sie Refactoring nicht mit dem Hinzufügen neuer Features. Das sind zwei verschiedene Aufgaben. Machen Sie sie in separaten Commits. \n
PHP-Refactoring-Beispiele: Von schlecht zu gut
\n\nSchauen wir uns ein echtes Beispiel an. Angenommen, wir haben eine Funktion zur Berechnung eines Rabatts. So sieht sie in einem typischen Legacy-Projekt aus:
\n\nVor dem Refactoring (schlechter Code)
\nfunction calculateDiscount($user, $order) {\n $discount = 0;\n if ($user->isVip()) {\n $discount = 10;\n if ($order->getTotal() > 1000) {\n $discount = 15;\n }\n }\n if (date('Y-m-d') == '2025-12-31') {\n $discount = $discount + 5;\n }\n if ($order->getItemsCount() > 5) {\n $discount = $discount + 3;\n }\n return $discount;\n}\n\nProbleme: Magische Daten, Zahlen als Konstanten, Vermischung von Logiken (Benutzer, Bestellung, Datum). Kommt morgen eine neue Aktion dazu, wird die Funktion noch länger.
\n\nNach dem PHP-Refactoring (guter Code)
\nclass DiscountCalculator {\n private const NEW_YEAR_DATE = '2025-12-31';\n \n public function calculate(User $user, Order $order): int {\n $discount = $this->getBaseDiscount($user) \n + $this->getHolidayBonus() \n + $this->getVolumeBonus($order);\n \n return min($discount, 50); // maximal 50%\n }\n \n private function getBaseDiscount(User $user): int {\n if ($user->isVip() && $user->getTotalSpent() > 1000) {\n return 15;\n }\n return $user->isVip() ? 10 : 0;\n }\n \n private function getHolidayBonus(): int {\n retu