Rector – le refactoring automatisé en PHP
Quand on travaille sur des projets PHP, surtout lorsqu’ils ont déjà plusieurs années derrière eux, une réalité finit toujours par s’imposer : le code vieillit. Les nouvelles versions de PHP introduisent de nouvelles syntaxes, des fonctions se déprécient, les frameworks évoluent et les standards de la communauté bougent. Mettre son code à jour devient vite un travail titanesque, répétitif, et souvent décourageant. C’est ici qu’intervient Rector, un outil qui a radicalement changé la manière dont on envisage la maintenance des projets PHP.
Rector est un vendor PHP qui se présente comme un compagnon de refactoring et de migration automatisée. Son but est simple : appliquer pour vous des transformations de code intelligentes et sûres, afin que vous puissiez moderniser vos projets sans devoir tout réécrire manuellement. Contrairement à un simple linter ou un analyseur statique, Rector est capable de modifier directement le code source. Il devient alors un assistant puissant pour faire évoluer une base de code en douceur, sans passer par une réécriture brutale.
L’un des points les plus séduisants avec Rector est sa capacité à se greffer à n’importe quel projet existant. Il suffit de l’installer via Composer et de lui fournir une configuration, pour ensuite lui indiquer quels types de règles appliquer. Ces règles, appelées “rectors”, sont des ensembles de transformations prédéfinies qui répondent à des besoins précis : passer d’une version de PHP à une autre, adopter les conventions PSR, remplacer des appels obsolètes d’un framework, ou encore simplifier des constructions trop verbeuses. Par exemple, si vous souhaitez migrer un projet de PHP 7.4 vers PHP 8.2, Rector pourra automatiser la grande majorité des changements syntaxiques nécessaires, qu’il s’agisse de transformer des array() en [], d’introduire les propriétés typées, ou encore de convertir des annotations Doctrine en attributs PHP natifs.
Ce qui rend l’expérience encore plus fluide, c’est la granularité du contrôle. Rector peut s’exécuter en mode “dry-run”, affichant simplement les changements qu’il aurait appliqués sans toucher au code. Cela permet aux développeurs de garder une maîtrise totale du processus et de valider chaque étape avant un commit. On peut ainsi l’intégrer dans une pipeline CI/CD et automatiser la migration progressive d’un codebase entier, tout en gardant la garantie que les tests continueront à passer.
Mais Rector ne se limite pas aux migrations. Il devient aussi un formidable outil pédagogique. Lorsqu’on l’introduit dans une équipe, il ne se contente pas de corriger le code : il éduque les développeurs en montrant les bonnes pratiques modernes. Chaque transformation appliquée est une sorte de rappel concret : « voici la manière actuelle de faire ». Sur le long terme, cela améliore non seulement la qualité technique du projet, mais aussi les compétences de l’équipe.
Bien entendu, comme tout outil de refactoring, Rector n’est pas magique. Il ne remplacera jamais la compréhension métier du développeur, ni le discernement humain dans les choix d’architecture. Cependant, pour toutes ces tâches fastidieuses et répétitives qui ne nécessitent pas de créativité, il agit comme un accélérateur de productivité. L’idée n’est pas de déléguer entièrement la responsabilité de la modernisation à l’outil, mais de l’utiliser comme un levier puissant pour gagner du temps et réduire les risques d’erreurs manuelles.
Dans un contexte où de nombreux projets sont encore bloqués sur d’anciennes versions de PHP ou de frameworks, Rector offre une porte de sortie élégante. Il devient une sorte de passerelle entre le code legacy et les standards actuels. En somme, il libère les développeurs du fardeau du “grand ménage” pour leur permettre de se concentrer sur ce qui compte vraiment : la valeur métier et les nouvelles fonctionnalités.
Adopter Rector, c’est donc faire le choix d’un code plus moderne, plus propre et plus maintenable, sans sacrifier son temps ni son énergie. C’est accepter que la maintenance d’un projet ne soit plus une corvée, mais un processus continu, automatisé, et presque agréable.
Pour illustrer son utilisation, prenons un exemple concret. Supposons que vous ayez un projet PHP 7.4 et que vous souhaitiez profiter des nouveautés de PHP 8.1, comme les propriétés typées ou encore l’usage des match. Après avoir installé Rector avec Composer (composer require rector/rector --dev), vous pouvez créer un fichier de configuration nommé rector.php à la racine de votre projet. Ce fichier indique quelles règles Rector doit appliquer.
Voici un exemple minimaliste :
<?php
declare(strict_types=1);
use Rector\Config\RectorConfig;
use Rector\Set\ValueObject\LevelSetList;
return static function (RectorConfig $rectorConfig): void {
// On indique à Rector d'analyser tout le dossier "src"
$rectorConfig->paths([
__DIR__ . '/src',
]);
// On choisit un ensemble de règles prédéfinies pour passer à PHP 8.1
$rectorConfig->sets([
LevelSetList::UP_TO_PHP_81,
]);
};
Une fois ce fichier en place, il ne vous reste plus qu’à lancer Rector. La commande suivante permet d’exécuter le refactoring tout en affichant les changements proposés sans les appliquer réellement :
vendor/bin/rector process --dry-run
Si tout est conforme à vos attentes, vous pouvez retirer l’option --dry-run et laisser Rector transformer vos fichiers source. Le gain de temps est impressionnant : en quelques minutes, des centaines de fichiers peuvent être modernisés, avec une cohérence parfaite et un risque d’erreurs humaines réduit à néant.
Ce genre de configuration peut bien sûr être enrichi. On peut mélanger plusieurs ensembles de règles, en activer ou désactiver certaines, ou encore définir des règles personnalisées adaptées au contexte spécifique d’un projet ou d’un framework. Cela fait de Rector non seulement un outil de migration, mais aussi un véritable garde-fou pour maintenir une base de code saine et à jour au fil des années.
Pour bien comprendre l’impact de Rector, rien ne vaut un exemple pratique.
Imaginons que vous ayez un code écrit en PHP 7.4, utilisant encore des annotations Doctrine et des array() un peu vieillots :
Avant Rector
<?php
namespace App\Entity;
/**
* @Entity
* @Table(name="users")
*/
class User
{
/**
* @var string
* @Column(type="string", length=100)
*/
private $name;
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}
Ce code fonctionne, mais il n’exploite pas les possibilités offertes par PHP 8.1 : propriétés typées, attributs, retours typés, etc.
Voyons maintenant ce que Rector peut en faire automatiquement.
Après Rector (avec règles UP_TO_PHP_81)
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: "users")]
class User
{
#[ORM\Column(type: "string", length: 100)]
private string $name;
public function setName(string $name): void
{
$this->name = $name;
}
public function getName(): string
{
return $this->name;
}
}
En une seule exécution, Rector a :
- Converti les annotations en attributs PHP natifs.
- Ajouté des types aux propriétés et aux paramètres.
- Généré un type de retour explicite pour les méthodes.
Le résultat est un code immédiatement plus lisible, plus robuste, et surtout aligné sur les bonnes pratiques actuelles.
Là où un développeur aurait passé des heures à réécrire classe par classe, Rector applique les transformations en quelques secondes, avec une homogénéité irréprochable.