Clean Code на PHP: принципы написания читаемого кода

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Clean Code на PHP: принципы и примеры

Каждый PHP-разработчик сталкивался с ситуацией, когда собственный код через пару месяцев становится непонятным. А что уж говорить о чужом коде, унаследованном от предыдущей команды. Это приводит к багам, долгому онбордингу новичков и нежеланию вносить изменения. Решение этой проблемы — принципы Clean Code (чистого кода), популяризированные Робертом Мартином (дядей Бобом). В этой статье мы разберем ключевые принципы Clean Code применительно к PHP и рассмотрим конкретные примеры.

1. Именование переменных, функций и классов

Правильное именование — основа читаемого кода. Имя должно отвечать на вопросы: "Что это?" и "Зачем это?". Не экономьте буквы в угоду краткости.

Плохой пример (плохой код)

<?php
function getData($d, $u) {
    $r = [];
    foreach ($d as $i) {
        if ($i['status'] === 'active' && $i['user_id'] === $u) {
            $r[] = $i;
        }
    }
    return $r;
}
?>

Хороший пример (чистый код)

<?php
function 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 строк.

Плохой пример (функция делает всё)

<?php
function 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;
}
?>

Хороший пример (разделение на маленькие функции)

<?php
class 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 saveOrder(int $userId, float $total): int
    {
        // Логика сохранения в БД
        return 123; // ID заказа
    }

    private function sendConfirmationEmail(string $email): void
    {
        // Логика отправки email
    }
}
?>

3. Комментарии: когда они нужны, а когда — нет

Чистый код самодокументируем. Комментарии не должны объяснять что делает код (это должна показывать структура и имена), а почему он делает это именно так. Избегайте закомментированного кода — используйте систему контроля версий.

Плохой пример (бесполезный комментарий)

<?php
// Увеличиваем счетчик на 1
$counter = $counter + 1;
?>

Хороший пример (объяснение бизнес-логики)

<?php
// Скидка 10% применяется только для новых клиентов (статус 'new')
// в первые 30 дней после регистрации
if ($user->getStatus() === 'new' && $user->getDaysSinceRegistration() < 30) {
    $total *= 0.9;
}
?>

Когда комментарии оправданы:

  • Сложные бизнес-правила.
  • Предупреждения о побочных эффектах.
  • Ссылки на внешние источники (баг-трекеры, документацию).
  • TODO и FIXME с указанием причины.

4. Форматирование и PSR-стандарты

PHP-FIG (PHP Framework Interop Group) разработала стандарты PSR, которые помогают писать единообразный код. Для Clean Code особенно важны PSR-1 (базовые правила) и PSR-12 (стиль кода).

Основные правила PSR-12:

  • Отступы — 4 пробела (не табуляция).
  • Открывающая фигурная скобка класса — на новой строке.
  • Открывающая фигурная скобка метода — на новой строке.
  • Открывающая фигурная скобка управляющих конструкций (if, foreach) — на той же строке.

Блоги

Рекомендаций по книгам