Clean Code en PHP : principes et exemples
Chaque développeur PHP a déjà été confronté à une situation où son propre code devient incompréhensible après quelques mois. Et que dire du code d'autrui, hérité de l'équipe précédente. Cela entraîne des bugs, une longue intégration des nouveaux arrivants et une réticence à apporter des modifications. La solution à ce problème réside dans les principes du Clean Code (code propre), popularisés par Robert Martin (Oncle Bob). Dans cet article, nous allons analyser les principes clés du Clean Code appliqués à PHP et examiner des exemples concrets.
1. Nommage des variables, fonctions et classes
Un nommage correct est la base d'un code lisible. Le nom doit répondre aux questions : "Qu'est-ce que c'est ?" et "À quoi ça sert ?". Ne lésinez pas sur les lettres au profit de la brièveté.
Mauvais exemple (mauvais code)
<?phpfunction getData($d, $u) { $r = []; foreach ($d as $i) { if ($i['status'] === 'active' && $i['user_id'] === $u) { $r[] = $i; } } return $r;}?>Bon exemple (code propre)
<?phpfunction getActiveOrdersByUser(array $orders, int $userId): array{ $activeOrders = []; foreach ($orders as $order) { if ($order['status'] === 'active' && $order['user_id'] === $userId) { $activeOrders[] = $order; } } return $activeOrders;}?>Règles de nommage :
- Variables — des noms :
$userName,$orderTotal. - Fonctions — des verbes :
calculateTotal(),sendEmail(). - Classes — des noms au singulier :
UserRepository,OrderProcessor. - Variables booléennes — commencez par
is,has,can:$isActive,$hasPermission. - Évitez les abréviations (
$usr), la translittération ($sozdanieZakaza) et les variables d'une seule lettre (sauf pour les compteurs de boucle$i).
2. Fonctions : petites et avec une seule responsabilité
Une fonction ne doit faire qu'une seule action et la faire bien. Si une fonction effectue plusieurs tâches, il faut la diviser. La taille idéale d'une fonction est de 10 à 20 lignes.
Mauvais exemple (la fonction fait tout)
<?phpfunction processOrder(array $orderData): bool{ // Validation if (empty($orderData['items'])) { return false; } // Calcul du coût $total = 0; foreach ($orderData['items'] as $item) { $total += $item['price'] * $item['quantity']; } // Sauvegarde en BDD $sql = "INSERT INTO orders (user_id, total, status) VALUES (?, ?, 'new')"; $stmt = $this->db->prepare($sql); $stmt->execute([$orderData['user_id'], $total]); // Envoi d'email mail($orderData['email'], 'Order Confirmation', 'Your order is placed'); return true;}?>Bon exemple (division en petites fonctions)
<?phpclass OrderService{ public function processOrder(array $orderData): bool { if (!$this->validateOrder($orderData)) { return false; } $total = $this->calculateTotal($orderData['items']); $orderId = $this->saveOrder($orderData['user_id'], $total); $this->sendConfirmationEmail($orderData['email']); return true; }
private function validateOrder(array $orderData): bool { return !empty($orderData['items']); }
private function calculateTotal(array $items): float { $total = 0; foreach ($items as $item) { $total += $item['price'] * $item['quantity']; } return $total; }
private function s