Refactoring PHP : quand l'appliquer et comment ne pas nuire à votre projet
\n\nTout développeur PHP rencontre un jour du code qu'il rêve de réécrire. Les projets legacy en PHP regorgent de « nombres magiques » (magic numbers), de fonctions longues comme un écran et de classes qui gèrent tout et n'importe quoi. Les démangeaisons de remettre de l'ordre sont fortes. Mais est-ce vraiment nécessaire ? Et si oui, comment effectuer un refactoring PHP de manière sécurisée et efficace ?
\n\nDans cet article, nous analyserons quand le refactoring est réellement indispensable et quand il vaut mieux laisser les choses en l'état. Vous découvrirez des exemples concrets de mauvais et de bon code en PHP, obtiendrez une checklist d'actions et comprendrez comment éviter de transformer une amélioration en catastrophe.
\n\nQuand le refactoring PHP est-il justifié ?
\n\nLe refactoring consiste à modifier la structure interne du code sans changer son comportement externe. Cela semble simple, mais en pratique, c'est l'une des opérations les plus risquées en développement. Voici les signes qu'il est temps d'envisager une amélioration de votre code PHP :
\n\n- \n
- Le code « sent mauvais » (code smells). Méthodes trop longues, duplication, classes god objects, noms de variables incompréhensibles. \n
- Ajouter une nouvelle fonctionnalité devient un calvaire. Si chaque pull request casse trois autres parties du code, c'est un signal d'alarme. \n
- Vous ne comprenez plus ce que fait une méthode une semaine après l'avoir écrite. Un mauvais code est un code qui nécessite des commentaires sur chaque ligne. \n
- Le principe de responsabilité unique (SRP) est violé. Une classe UserManager qui crée des utilisateurs, envoie des emails et génère des rapports est un candidat typique au refactoring. \n
Mais il existe des situations où le refactoring PHP peut nuire :
\n- \n
- La deadline est demain et le code fonctionne. \n
- Il n'y a pas de tests. Sans eux, toute modification est une roulette russe. \n
- Le code est écrit « à la va-vite » pour un prototype qui sera jeté demain. \n
Règles pour un refactoring sécurisé
\n\nAvant de vous lancer dans le refactoring PHP, retenez trois règles d'or :
\n\n- \n
- Couvez le code de tests. Au moins des tests d'intégration. S'il n'y en a pas, écrivez-en pour les parties critiques. \n
- Refactorisez par petites étapes. Une méthode à la fois. Poussez, vérifiez, continuez. \n
- Ne mélangez pas refactoring et ajout de fonctionnalités. Ce sont deux tâches distinctes. Faites-les dans des commits séparés. \n
Exemples de refactoring PHP : du mauvais au bon code
\n\nRegardons des exemples concrets. Imaginons une fonction pour calculer une remise. Voici à quoi elle ressemble dans un projet legacy typique :
\n\nAvant refactoring (mauvais 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\nProblèmes : dates magiques, nombres en dur, logiques mélangées (utilisateur, commande, date). Si une nouvelle promotion apparaît demain, la fonction deviendra encore plus longue.
\n\nAprès refactoring PHP (bon 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); // pas plus de 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