Введение: почему чистый код на PHP — это не роскошь, а необходимость
Каждый PHP-разработчик хотя бы раз сталкивался с ситуацией, когда простой баг в production-среде превращается в многочасовую охоту за «дьяволом в деталях». Чаще всего причина кроется не в сложности логики, а в грязном коде: бессмысленные имена переменных, функции длиной в 500 строк, отсутствие типов и комментарии-враньё. Clean Code (Чистый код) — это не просто эстетика. Это инструмент, который снижает стоимость поддержки проекта в 3–5 раз и позволяет новым членам команды вливаться в проект за часы, а не недели.
В этой статье мы разберём ключевые принципы Clean Code применительно к PHP, подкрепив их реальными примерами до и после рефакторинга. Вы узнаете, как применять стандарты PSR, принципы SOLID и простые правила нейминга, чтобы ваш код говорил сам за себя.
1. Именование переменных, функций и классов: говорите на языке бизнеса
Плохое имя — главный враг читаемости. Если переменная называется $a или $data, каждый раз, читая код, вы тратите ментальные ресурсы на расшифровку. Правило простое: имя должно отвечать на вопрос «Что это?» или «Что делает?»
Плохой пример
<?php
// Что такое $d? Почему $x = 2?
$d = new DateTime();
$x = 2;
$y = $d->modify('+' . $x . ' days');
echo $y->format('Y-m-d');
?>
Хороший пример (Clean Code)
<?php
$currentDate = new DateTime();
$daysToAdd = 2;
$futureDate = $currentDate->modify('+' . $daysToAdd . ' days');
echo $futureDate->format('Y-m-d');
?>
Дополнительные правила:
- Классы и интерфейсы — существительные:
UserRepository,PaymentGatewayInterface. - Методы — глаголы:
getUserById(),sendEmailNotification(). - Булевы переменные — префиксы
is,has,can:$isActive,$hasPermission. - Избегайте сокращений:
$cnt→$count,$usr→$user.
2. Функции и методы: принцип единой ответственности (SRP) в действии
Одна функция — одно действие. Если вы видите функцию длиннее 20–30 строк, скорее всего, её можно разбить. В PHP это особенно актуально, так как отсутствие строгой типизации (до PHP 7.4) провоцирует «свалки» кода.
Плохой пример: функция-швейцарский нож
<?php
function processOrder(array $orderData): array
{
// Валидация
if (empty($orderData['email'])) {
throw new InvalidArgumentException('Email required');
}
// Сохранение в БД
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
$stmt = $pdo->prepare('INSERT INTO orders (email, total) VALUES (?, ?)');
$stmt->execute([$orderData['email'], $orderData['total']]);
// Отправка email
mail($orderData['email'], 'Order Confirmed', 'Thank you!');
// Логирование
file_put_contents('log.txt', 'Order processed: ' . $orderData['email'] . PHP_EOL, FILE_APPEND);
return ['status' => 'success'];
}
?>
Хороший пример: разделение ответственности
<?php
class OrderProcessor
{
private OrderValidator $validator;
private OrderRepository $repository;
private MailService $mailer;
private Logger $logger;
public function __construct(
OrderValidator $validator,
OrderRepository $repository,
MailService $mailer,
Logger $logger
) {
$this->validator = $validator;
$this->repository = $repository;
$this->mailer = $mailer;
$this->logger = $logger;
}
public function process(array $orderData): array
{
$this->validator->validate($orderData);
$order = $this->repository->save($orderData);
$this->mailer->sendConfirmation($order);
$this->logger->log('Order processed: ' . $order['email']);
return ['status' => 'success', 'order_id' => $order['id']];
}
}
?>
Теперь каждый класс отвечает только за свою зону: валидация, работа с БД, отправка писем и логирование. Такой код легко тестировать и модифицировать.
3. Комментарии: когда они нужны, а когда — вредны
Роберт Мартин (автор книги «Clean Code») утверждает: «Хороший код не требует комментариев». Комментарий — это признак неудачной попытки объяснить, что делает код. Вместо того чтобы писать комментарий, улучшите сам код.
Плохой пример: комментарий-извинение
<?php
// Увеличиваем счетчик на 1, потому что так надо
$counter = $counter + 1;
// Проверяем, если пользователь админ
if ($user->role == 1) {
// ...
}
?>
Хороший пример: самодокументируемый код
<?php
$counter++;
if ($user->isAdmin()) {
// ...
}
?>
Когда комментарии оправданы:
- Пояснение бизнес-правил, которые невозможно выразить кодом (например, ссылка на закон или регламент).
- Предупреждение о побочных эффектах (например,
// Этот метод меняет глобальное состояние). - Todo-заметки для будущих доработок:
// TODO: заменить на кэширование.
4. Стандарты PSR и форматирование: единый стиль для команды
PHP Framework Interop Group (PHP-FIG) разработала стандарты PSR,