Пишем чистый код на PHP: руководство для тех, кто уважает себя и коллег

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

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

Начать курс

Введение: почему «чистый код» — это не про педантичность, а про деньги и нервы

Представьте, что вы заходите в старый проект на PHP, написанный год назад. Вы открываете файл index.php, а там — мешанина из HTML, SQL-запросов, echo и функций с именами типа f1(). Знакомо? Если да, то вы либо новичок, который только начинает свой путь, либо опытный разработчик, которому достался «легаси» проект.

Чистый код на PHP — это не дань моде и не прихоть тимлида. Это инструмент, который экономит часы, нервы и деньги. В этой статье мы разберем, как превратить ваш PHP-код из «грязного черновика» в «чистовик», который будет радовать вас и ваших коллег. Мы поговорим о стандартах PSR, принципах SOLID, правильном нейминге и дадим реальные примеры. Поехали!

1. Философия чистого кода: главные принципы

Прежде чем нырять в синтаксис, давайте договоримся о правилах игры. Чистый код — это код, который:

  • Понятен без комментариев (хотя комментарии иногда нужны).
  • Легко тестируется.
  • Не боится рефакторинга.
  • Соблюдает единый стиль во всем проекте.

Роберт Мартин (Дядюшка Боб) в своей книге «Чистый код» сказал: «Единственный способ быстро писать — это писать хорошо». Если вы пишете быстро и грязно, то через месяц вы будете тратить в 10 раз больше времени на отладку. Давайте учиться на чужих ошибках, а не на своих.

2. Стандарты PSR: ваш первый шаг к порядку

В мире PHP есть PSR (PHP Standards Recommendations) — это рекомендации, которые приняло сообщество. Если вы не используете их, вы как минимум усложняете жизнь себе и коллегам, которые будут читать ваш код.

2.1 PSR-1 и PSR-12: Базовый стиль кодирования

PSR-1 задает общие правила, а PSR-12 — расширенный стиль. Вот несколько ключевых моментов:

  • Файлы должны использовать только <?php или <?=.
  • Кодировка файлов — UTF-8 без BOM.
  • Имена классов должны быть в StudlyCaps (например, UserController).
  • Имена методов и свойств — в camelCase (например, getUserName()).
  • Отступы — 4 пробела (не табуляция!).

Пример плохого кода:

<?
class user_controller {
	function Get_User_Name($id) {
		$name = Db::query("SELECT name FROM users WHERE id=$id");
		return $name;
	}
}

Пример хорошего кода (PSR-12):

<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\User;

class UserController
{
    public function getUserName(int $id): ?string
    {
        $user = User::find($id);
        return $user ? $user->getName() : null;
    }
}

Видите разницу? Второй вариант читается как книга: сразу понятно, что делает метод, какие типы данных он принимает и возвращает.

2.2 PSR-4: Автозагрузка классов

Забудьте про require_once в каждом файле. Используйте Composer и PSR-4. Это позволяет подключать классы автоматически по пространству имен. Структура папок должна соответствовать неймспейсам:

src/
  App/
    Controllers/
      UserController.php
    Models/
      User.php
    Services/
      PaymentService.php

В composer.json это настраивается одной строкой:

{
    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    }
}

3. Правильный нейминг: как не назвать переменную $a

Нейминг — это 50% успеха. Плохое имя переменной может запутать даже гения. Давайте разберем частые ошибки.

3.1 Избегайте сокращений (кроме очевидных)

Плохо: $usr_nm, $cnt, $d.

Хорошо: $userName, $counter, $date.

3.2 Булевы переменные должны звучать как вопрос

Плохо: $flag, $status.

Хорошо: $isActive, $hasAccess, $canEdit.

3.3 Имена функций должны быть глаголами

Плохо: userData() — непонятно, что делает.

Хорошо: getUserData(), saveUser(), validateEmail().

3.4 Пример рефакторинга нейминга

Было (ужас):

function gud($uid) {
    $q = "SELECT * FROM users WHERE id=" . $uid;
    $r = mysqli_query($conn, $q);
    $d = mysqli_fetch_assoc($r);
    return $d['name'];
}

Стало (красота):

public function getUserNameById(int $userId): string
{
    $user = $this->userRepository->find($userId);
    
    if (!$user) {
        throw new UserNotFoundException("User with ID $userId not found");
    }
    
    return $user->getName();
}

Теперь даже джуниор поймет, что делает этот код, не заглядывая в документацию.

4. Магия SOLID: 5 принципов, которые спасут ваш проект

SOLID — это не абстрактная теория, а практические правила для объектно-ориентированного программирования. Давайте разберем их на примерах PHP.

4.1 S — Single Responsibility (Принцип единственной ответственности)

Класс должен иметь только одну причину для изменения. Если ваш класс Order умеет и сохранять заказ, и отправлять email, и генерировать PDF-счет — это нарушение SRP.

Плохо:

class Order {
    public function save() { /* ... */ }
    public function sendEmail() { /* ... */ }
    public function generatePdf() { /* ... */ }
}

Хорошо (разделяем ответственность):

class OrderRepository {
    public function save(Order $order) { /* ...                

Блоги

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