Réusinage de code legacy en PHP : comment transformer le chaos en ordre
Chaque développeur PHP rencontre tôt ou tard du code legacy — un projet ancien, mal documenté et souvent non fonctionnel. Au lieu de tout réécrire depuis zéro (ce qui est risqué et coûteux), un réusinage judicieux permet d'améliorer le code sans interrompre les processus métier. Dans cet article, nous verrons comment réusiner en toute sécurité des projets PHP legacy tout en préservant leur fonctionnement.
1. Évaluation et préparation : par où commencer le réusinage du code legacy
Avant de toucher au code, il est nécessaire de comprendre son état actuel. Sautez cette étape — et vous risquez de tout casser.
- Créez une sauvegarde — un dump complet de la base de données et des fichiers du projet.
- Effectuez un audit — trouvez tous les points d'entrée, les dépendances et les "boîtes noires". Utilisez
greppour rechercher les fonctionsinclude,require,evaletmysql_*. - Configurez l'environnement — montez une copie locale du projet (Docker, Vagrant ou XAMPP).
- Ajoutez la journalisation —
error_loget la surveillance aideront à suivre les erreurs après les modifications.
Exemple d'audit simple via la console :
# Recherche des fonctions mysql obsolètesgrep -rn "mysql_query\\|mysql_connect\\|mysql_fetch" /path/to/legacy/project/Important : si le projet n'a pas de tests — le réusinage devient un jeu de roulette russe. En premier lieu, couvrez la logique critique avec des tests (même s'il s'agit de scénarios manuels consignés dans un document).
2. Stratégie de réusinage : petits pas pour grands changements
La meilleure stratégie pour le legacy est l'amélioration progressive. N'essayez pas de réécrire tout le projet en un week-end. Utilisez l'approche de la "règle du boy-scout" : laissez le code plus propre que vous ne l'avez trouvé.
2.1. Isolez les modifications
Chaque modification doit être minimale et atomique. Exemple : renommer une variable dans un fichier, puis extraire le code dupliqué dans une fonction.
<?php// Avant le réusinage (legacy)$sql = "SELECT * FROM users WHERE id = " . $_GET['id'];$result = mysql_query($sql);
// Après : au moins on échappe$id = (int)$_GET['id'];$sql = "SELECT * FROM users WHERE id = $id";$result = mysqli_query($link, $sql);?>2.2. Utilisez des outils d'automatisation
- PHPStan — analyse statique, détecte les erreurs sans exécuter le code.
- Rector — réusinage automatique (PSR-12, remplacement des fonctions obsolètes).
- PHP CodeSniffer — vérification du style de code.
- PHPUnit — tests unitaires.
Exemple d'exécution de Rector pour remplacer mysql_* par mysqli_* :
vendor/bin/rector process src/ --set mysql-to-mysqli3. Techniques concrètes de réusinage de code PHP
3.1. Remplacement du "code spaghetti" par la POO
Le legacy est souvent écrit comme un seul fichier énorme mêlant HTML et PHP. Séparez la logique en classes et fonctions.
<?php// Mauvais : code mélangé$user = getUser($_GET['id']);echo "<h1>Bonjour, " . $user['name'] . "</h1>";if ($_POST['action'] === 'save') { saveUser($_POST);}
// Bon : séparation des responsabilitésclass UserController { public function show(int $id): void { $user = $this->userRepository->find($id); $this->render('profile', ['user' => $user]); }}?>3.2. Suppression du code "mort"
Les fonctions inutilisées, les commentaires, les blocs commentés — tout cela crée du bruit. Supprimez sans pitié, mais vérifiez via git log que le code n'est pas utilisé ailleurs.
// Recherche de fonctions inutilisées (nécessite PHPStan)vendo