Clean Code en PHP: principios y ejemplos
Cada desarrollador de PHP se ha enfrentado a la situación en la que su propio código se vuelve incomprensible después de un par de meses. Y qué decir del código ajeno, heredado del equipo anterior. Esto provoca errores, una larga incorporación de nuevos miembros y la falta de voluntad para realizar cambios. La solución a este problema son los principios de Clean Code (código limpio), popularizados por Robert Martin (tío Bob). En este artículo, analizaremos los principios clave de Clean Code aplicados a PHP y veremos ejemplos concretos.
1. Nombrado de variables, funciones y clases
Un nombrado correcto es la base de un código legible. El nombre debe responder a las preguntas: "¿Qué es esto?" y "¿Para qué sirve?". No ahorres letras en aras de la brevedad.
Mal ejemplo (código malo)
<?phpfunction getData($d, $u) { $r = []; foreach ($d as $i) { if ($i['status'] === 'active' && $i['user_id'] === $u) { $r[] = $i; } } return $r;}?>Buen ejemplo (código limpio)
<?phpfunction getActiveOrdersByUser(array $orders, int $userId): array{ $activeOrders = []; foreach ($orders as $order) { if ($order['status'] === 'active' && $order['user_id'] === $userId) { $activeOrders[] = $order; } } return $activeOrders;}?>Reglas de nombrado:
- Variables — sustantivos:
$userName,$orderTotal. - Funciones — verbos:
calculateTotal(),sendEmail(). - Clases — sustantivos en singular:
UserRepository,OrderProcessor. - Variables booleanas — comienza con
is,has,can:$isActive,$hasPermission. - Evita abreviaturas (
$usr), transliteraciones ($sozdanieZakaza) y variables de una sola letra (excepto contadores de bucle$i).
2. Funciones: pequeñas y con una sola responsabilidad
Una función debe hacer solo una acción y hacerla bien. Si una función realiza varias tareas, debe dividirse. El tamaño ideal de una función es de 10 a 20 líneas.
Mal ejemplo (la función lo hace todo)
<?phpfunction processOrder(array $orderData): bool{ // Validación if (empty($orderData['items'])) { return false; } // Cálculo del costo $total = 0; foreach ($orderData['items'] as $item) { $total += $item['price'] * $item['quantity']; } // Guardado en la BD $sql = "INSERT INTO orders (user_id, total, status) VALUES (?, ?, 'new')"; $stmt = $this->db->prepare($sql); $stmt->execute([$orderData['user_id'], $total]); // Envío de email mail($orderData['email'], 'Order Confirmation', 'Your order is placed'); return true;}?>Buen ejemplo (división en funciones pequeñas)
<?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