Clean Code на PHP: принципы и примеры
Каждый PHP-разработчик сталкивался с ситуацией, когда собственный код через пару месяцев становится непонятным. А что уж говорить о чужом коде, унаследованном от предыдущей команды. Это приводит к багам, долгому онбордингу новичков и нежеланию вносить изменения. Решение этой проблемы — принципы Clean Code (чистого кода), популяризированные Робертом Мартином (дядей Бобом). В этой статье мы разберем ключевые принципы Clean Code применительно к PHP и рассмотрим конкретные примеры.
1. Именование переменных, функций и классов
Правильное именование — основа читаемого кода. Имя должно отвечать на вопросы: "Что это?" и "Зачем это?". Не экономьте буквы в угоду краткости.
Плохой пример (плохой код)
<?phpfunction getData($d, $u) { $r = []; foreach ($d as $i) { if ($i['status'] === 'active' && $i['user_id'] === $u) { $r[] = $i; } } return $r;}?>Хороший пример (чистый код)
<?phpfunction getActiveOrdersByUser(array $orders, int $userId): array{ $activeOrders = []; foreach ($orders as $order) { if ($order['status'] === 'active' && $order['user_id'] === $userId) { $activeOrders[] = $order; } } return $activeOrders;}?>Правила именования:
- Переменные — существительные:
$userName,$orderTotal. - Функции — глаголы:
calculateTotal(),sendEmail(). - Классы — существительные в единственном числе:
UserRepository,OrderProcessor. - Булевы переменные — начинайте с
is,has,can:$isActive,$hasPermission. - Избегайте сокращений (
$usr), транслита ($sozdanieZakaza) и однобуквенных переменных (кроме счетчиков циклов$i).
2. Функции: маленькие и с одной ответственностью
Функция должна делать только одно действие и делать его хорошо. Если функция выполняет несколько задач — её нужно разбить. Идеальный размер функции — 10–20 строк.
Плохой пример (функция делает всё)
<?phpfunction processOrder(array $orderData): bool{ // Валидация if (empty($orderData['items'])) { return false; } // Расчет стоимости $total = 0; foreach ($orderData['items'] as $item) { $total += $item['price'] * $item['quantity']; } // Сохранение в БД $sql = "INSERT INTO orders (user_id, total, status) VALUES (?, ?, 'new')"; $stmt = $this->db->prepare($sql); $stmt->execute([$orderData['user_id'], $total]); // Отправка email mail($orderData['email'], 'Order Confirmation', 'Your order is placed'); return true;}?>Хороший пример (разделение на маленькие функции)
<?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