Александр Некрасов · Автономное руководство

PHP: полный мануал с примерами, функциями и ООП

Разделы этой страницы
  1. Понятный код: имена, отступы и комментарии
  2. Как записать маленький расчёт так, чтобы его прочитали
  3. Код читают чаще, чем пишут
  4. Единый стиль без ручной борьбы с пробелами
  5. Комментарий объясняет причину и ограничение
  6. Что проверять перед передачей кода
  7. Код и руководство с собой
PHP 8.5.11149 глав4458 карточек справочника
Дерево руководства

Глава 5 · С нуля → практика

Понятный код: имена, отступы и комментарии

Пишем так, чтобы через полгода было видно, откуда берутся данные и почему приняты решения.

Как записать маленький расчёт так, чтобы его прочитали

Задача — посчитать две упаковки чая по 150 рублей. Хорошее оформление позволяет увидеть цену, количество и результат ещё до чтения пояснения. Имя выбирайте по смыслу: $unitPriceRubles лучше $a, когда важно, что это цена одной штуки именно в рублях. В этих вводных примерах суммы целые; расчёт дробных денег отдельно разобран ниже.

Цена, количество и итог названы прямоСамостоятельный пример
<?php
$unitPriceRubles = 150;
$quantity = 2;

// В учебном каталоге цены целые; доставка считается отдельно.
$totalRubles = $unitPriceRubles * $quantity;
echo 'Товары: ', $totalRubles, " руб.\n";
Ожидаемый результат
Товары: 300 руб.

Пробелы вокруг = и * отделяют части выражения. Пустая строка отделяет исходные данные от расчёта. Комментарий объясняет допущение про цены и доставку, а не пересказывает умножение.

Одна инструкция — одна строка; внутри фигурных скобок используйте четыре пробела отступа. { } ограничивают блок, а отступ помогает человеку увидеть его. PHP не определяет вложенность количеством пробелов. Короткий комментарий начинается с //, многострочный — с /* и заканчивается */. Не прячьте старую программу в комментариях: историю хранит система контроля версий.

Попробуйте сами. Добавьте $deliveryRubles = 50 и назовите итог с доставкой.

Разбор решения

Например: $payableRubles = $totalRubles + $deliveryRubles; результат 350. Разные имена сохраняют различие между стоимостью товаров и суммой к оплате.

Дальше расчёт получает имя через собственную функцию. Затем вернитесь к разделам ниже: там форматирование, комментарии и PHPDoc применены к коду с ветвлениями и массивами.

Код читают чаще, чем пишут

Наглядная модель

Понятные имена оставляют маршрут для читателя

Через месяц нужно изменить расчёт корзины. Названия должны помогать найти данные, действие и результат без расшифровки каждой строки.

  1. $cartItems — позиции корзины

    Имя объясняет, что за данные пришли в расчёт.

  2. calculateTotal() — посчитать итог

    Имя функции называет выполняемое действие.

  3. $totalKopecks — итог в копейках

    Имя результата дополнительно показывает единицу измерения.

Отступы показывают вложенность, пробелы разделяют части выражения. Комментарий объясняет причину: например, почему расчёт ведётся в копейках. Пересказывать очевидное действие каждой строки не нужно.

Представьте дежурство в магазине: покупателю начислена неверная скидка, и другой разработчик открывает ваш файл ночью. Название calculateDiscountKopecks объясняет больше, чем process2. Переменная $deliveryTimeoutSeconds показывает единицу измерения, $isPaid — логическое состояние, $orderIds — набор идентификаторов. Удачное имя сокращает число вопросов к автору. Не нужно механически делать каждое имя длинным: $index понятен в коротком цикле, но $data недостаточно для аргумента, где ожидается проверенный заказ.

Разделяйте получение данных, проверку, расчет и вывод. Функция расчета не должна незаметно читать $_POST или печатать HTML: иначе ее нельзя без изменений использовать в CLI-импорте или тесте. Начинайте с небольших функций по одной ответственности. Десяток строк, называющих бизнес-правило, обычно легче поддерживать, чем одно вложенное выражение на три строки.

Единый стиль без ручной борьбы с пробелами

PSR-12 задает распространенную основу: четыре пробела вместо табуляции, последовательное оформление скобок, пробелы у операторов, один оператор на строку. Сохраните UTF-8 без BOM, переносы LF и завершающий перевод строки. Для существующего проекта важнее согласованность с его стандартом; массовое переформатирование не смешивают с исправлением логики. Настройте форматтер в редакторе и проверку в CI, чтобы спор о пробелах не занимал ревью.

Читаемое правило бесплатной доставкиСамостоятельный пример
<?php
declare(strict_types=1);

function deliveryPriceKopecks(int $subtotalKopecks, bool $isPickup): int
{
    if ($subtotalKopecks < 0) {
        throw new InvalidArgumentException('Сумма не может быть отрицательной');
    }
    if ($isPickup || $subtotalKopecks >= 500000) {
        return 0;
    }

    return 29900;
}
echo deliveryPriceKopecks(250000, false), "\n";
echo deliveryPriceKopecks(250000, true), "\n";
Ожидаемый результат
29900
0

Имя возвращаемого значения содержит копейки. Ранний return отделяет случаи бесплатной доставки; отрицательный ввод не маскируется. Скобки и пустая строка обозначают смысловые блоки, а не декоративные интервалы.

Комментарий объясняет причину и ограничение

Комментарий «увеличиваем счетчик» рядом с ++$count повторяет синтаксис. Полезнее: «поставщик считает повторную отправку новым заказом, поэтому используем сохраненный ключ идемпотентности». Пишите, какое внешнее ограничение или бизнес-решение объясняет необычный код. Ссылку на задачу добавляйте вместе с краткой причиной: одна ссылка теряет смысл после смены трекера. TODO должен содержать конкретное условие завершения, иначе он становится постоянной частью архитектуры.

PHPDoc описывает форму массива и правило округленияСамостоятельный пример
<?php
declare(strict_types=1);

/**
 * @param list<array{priceKopecks: int, quantity: int}> $items
 * Скидка применяется к заказу целиком, чтобы сумма строк не расходилась с чеком.
 */
function subtotalKopecks(array $items): int
{
    $subtotal = 0;
    foreach ($items as $item) {
        $subtotal += $item['priceKopecks'] * $item['quantity'];
    }

    return $subtotal;
}
echo subtotalKopecks([['priceKopecks' => 15000, 'quantity' => 3]]), "\n";
Ожидаемый результат
45000

PHPDoc помогает IDE и статическому анализатору, но сам PHP не проверяет внутреннюю форму массива по комментарию. Здесь вход уже нормализован; проверка внешнего JSON показана отдельно. Комментарий о скидке объясняет соседнее проектное решение, а не утверждает, что функция уже ее применяет.

Что проверять перед передачей кода

  • Можно ли понять вход, результат и единицы измерения без просмотра всей программы?
  • Отделены ли ошибки ввода от недоступности сервиса?
  • Не скрывает ли короткое имя важное различие: сырой текст и безопасный HTML, ID и порядковый номер?
  • Не остались ли закомментированные пароли, var_dump и отладочные выходы?
  • Есть ли тест границы, а не только обычного числа?

Документируйте публичный контракт: исключения, допустимые диапазоны, изменение переданного объекта, побочные эффекты. Для стандартного int $count не требуется комментарий «целое число». Для массива строк поставщика полезна форма данных и объяснение, какие поля необязательны. Избыточные комментарии устаревают так же, как код; удаляйте неверное объяснение одновременно с изменением реализации.

Попробуйте сами. Переименуйте $t и $a в функции, которая ждет ответ API и ограничивает число повторов. Добавьте один полезный комментарий.

Разбор решения

$timeoutSeconds и $maxAttempts называют две разные величины. Комментарий может объяснять, почему предел 3 согласован с SLA поставщика. Комментарий «ждем указанное число секунд» не добавляет знания.

Источники и обсуждения

Код и руководство с собой

Скачайте самостоятельные примеры с исходными данными, инструкциями и ожидаемыми результатами. Примеры HTTP и фрагменты для проекта помечены отдельно: им нужно указанное окружение.

Код не исполняется на сайте. Скачайте нужный пример и запускайте его в своём локальном окружении.

Материалы сверены 2026-10-12. Примеры и объяснения написаны для этого руководства; источники и обсуждения доступны в каждой главе.