JNTZN

Метка: ci

  • Руководство по PHP-форматировщику: инструменты, лучшие практики и настройка

    Руководство по PHP-форматировщику: инструменты, лучшие практики и настройка

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

    Хороший PHP-форматировщик решает это, снимая решения по стилю из рук человека. Вместо того чтобы спорить о размещении скобок или переносе строк в каждом pull-запросе, вы задаёте правила один раз, запускаете инструмент автоматически и поддерживаете чистоту кодовой базы с этого момента.

    Для индивидуальных разработчиков это означает более быструю работу и меньше отвлекающих факторов. Для агентств, стартапов и больших инженерных команд это означает последовательный код, стабильные диффы, упрощённую адаптацию и более плавные конвейеры CI/CD. Самое приятное — мощные инструменты форматирования PHP либо бесплатны, либо с открытым исходным кодом, либо уже встроены в рабочие процессы, которые вы, возможно, используете сегодня; см. примеры инструментов.

    Side-by-side visual of 'messy' PHP code vs 'formatted' PHP code: left pane shows cramped, inconsistent indentation, mixed brace styles, and noisy diffs; right pane shows clean, consistently indented PSR-12 style with ordered imports and aligned operators. Add a small caption or icon showing slowed review (snail) on the messy side and faster review (rocket/check) on the formatted side.

    Что такое PHP-форматировщик и почему это важно

    PHP-форматировщик — это инструмент, который переписывает ваш код так, чтобы он следовал единообразному стилю. Он обрабатывает отступы, пробелы, переносы строк, размещение скобок, порядок импортов и другие правила верстки. Цель не в изменении того, что делает код, а в изменении того, как он выглядит, чтобы людям было читать его легче.

    A simple Venn/stacked diagram contrasting Formatter, Linter, and Static Analyzer: three labeled boxes or circles showing Formatter = presentation/style (indentation, spacing, line breaks), Linter = rule violations/syntax checks, Static Analyzer = deeper type/logic issues. Include brief example labels inside each (e.g., formatter: brace placement; linter: unused variable warning; static analyzer: type mismatch).

    Это делает форматировщик отличным от линтера или статического анализатора. Форматировщик фокусируется на представлении и стиле, линтер проверяет синтаксические проблемы и нарушения правил, а статический анализатор углубляется, чтобы искать проблемы с типами, неиспользуемый код, рискованную логику и архитектурные проблемы. На практике мощные PHP‑воркфлоу часто используют все три.

    Причина важности форматирования проста. Команды читают код гораздо чаще, чем пишут его. Кодовая база с единообразным стилем кажется предсказуемой. Вы можете быстрее сканировать функции, чище сравнивать изменения и тратить время обзора кода на архитектуру или баги, а не спорить о пробелах и табах. Это особенно ценно в проектах с открытым исходным кодом, передаче работы клиенту, корпоративных репозиториях и любых настройках с автоматическими Git‑хуками или проверками CI. Если несколько авторов работают над одним и тем же кодом каждую неделю, форматировщик быстро окупится.

    Как работает форматирование PHP: ключевые принципы и правила

    Большинство современных PHP форматтеров читают файлы как токены, а некоторые инструменты работают ближе к разобранной структуре синтаксиса. Они не просто выполняют слепую замену текста. Они анализируют код, понимают, где начинаются и заканчиваются ключевые слова, операторы, строки, комментарии и блоки, затем переписывают файл в соответствии с настроенными правилами.

    Именно поэтому надлежащий форматировщик может безопасно нормализовать код, который включает сложный синтаксис, например анонимные классы, объединённые типы, атрибуты, выражения match, блоки heredoc и nowdoc, а также новые возможности языка PHP 8+. Слабый форматировщик может сломать эти случаи. Зрелённый форматирователь делает это предсказуемо.

    Основные правила форматирования

    На практике большинство форматтеров применяют одни и те же группы правил. Они нормализуют отступы, размещение скобок, пробелы вокруг операторов, переносы строк, форматирование массивов и порядок импортов. Многие инструменты также удаляют неиспользуемые импорты, выравнивают многострочные выражения и приводят к единому стилю пустых строк между членами класса. Ключевое качество — идемпотентность. Это означает, что если запустить форматировщик дважды, второй проход не произведёт дополнительных изменений. Идемпотентные инструменты создают стабильные диффы, уменьшают шум в pull‑запросах и делают CI‑прохождения более надёжными.

    Стандарты PSR и руководства по стилю

    В экосистеме PHP наиболее известны PSR-1, PSR-2, и особенно PSR-12. PSR-12 — современная базовая точка отсчёта, с которой начинают многие команды, так как она задаёт широко принятая структура форматирования и верстки. Самые сильные форматтеры позволяют начать с PSR-12, а затем накладывать поверх него пользовательские настройки, такие как порядок импортов, завершающие запятые или обёртывание аргументов.

    Детерминированное и настраиваемое форматирование

    Некоторые инструменты весьма навязчивы и стремятся выдать один предсказуемый результат. Другие очень настраиваемы и позволяют командам настраивать десятки правил. Если вы работаете в небольшой команде или solo, ориентированный на единое мнение форматтер может сэкономить время, снижая усталость от решений. Если вы поддерживаете устаревшее приложение или хотите соответствовать существующему внутреннему руководству по стилю, часто лучше подойдет более настраиваемый инструмент.

    Screenshot of github.com

    1. PHP-CS-Fixer

    PHP-CS-Fixer — один из самых широко используемых инструментов форматирования PHP, и по уважительной причине. Он быстр, зрел и очень настраиваем, создан специально для принуждения и исправления код‑стандартов в проектах PHP. Если нужен серьёзный форматтер, который может масштабироваться от личного проекта до крупной производственной кодовой базы, это часто первый инструмент, который стоит оценить.

    Особенность PHP-CS-Fixer — баланс между разумными пресетами и глубокой настройкой. Можно начать с набора правил, например @PSR12, затем добавлять или убирать отдельные фиксаторы по мере формирования стиля командой. Эта гибкость полезна для агентств, продуктовых команд и поддерживающих долгоживущие кодовые базы, которым нужна консистентность без потери контроля. Ключевые возможности включают настраиваемые наборы правил на основе PSR и общественных пресетов, автоматическую фиксацию кода, вывод диффов для обзора изменений перед коммитом, кеширование для ускорения повторных прогонов и хорошую совместимость с CI и Git‑хуками.

    PHP-CS-Fixer очень гибок для пользовательских соглашений команды, отлично подходит для автоматизации в pre‑commit хуках и CI, и широко применяется благодаря сильной экосистеме. Может казаться ошеломляющим новичкам, и некоторые рискованные фиксаторы требуют тщательного тестирования перед широким внедрением. Цена проста: PHP-CS-Fixer бесплатен и с открытым исходным кодом.

    Screenshot of pear.php.net

    2. PHP_CodeSniffer и phpcbf

    PHP_CodeSniffer, обычно именуемый как phpcs, наиболее известен обнаружением нарушений стандартов кодирования. Его компаньон phpcbf может автоматически исправлять многие из этих нарушений. Вместе они образуют надёжный конвейер обеспечения соблюдения стандартов для команд, которые ценят соответствие правилам и аудит.

    Эта связка особенно полезна, когда проект нуждается в обнаружении проблем стиля так же сильно, как и их исправлении. Во многих организациях phpcs выступает в роли gatekeeper стандартов в CI, в то время как phpcbf обрабатывает автоматическую очистку там, где возможно. Если ваш рабочий процесс сильно опирается на формальные стандарты и наборы правил, эта цепочка инструментов заслуживает серьёзного рассмотрения. Основные возможности включают валидацию на основе набора правил через конфигурацию XML, поддержку официальных стандартов, таких как PSR-12, автоматические исправления через phpcbf, хорошую интеграцию в редакторы и CI и детальные отчёты для команд, которым нужна видимость нарушений.

    phpcs отлично подходит для обеспечения соблюдения и аудита, с понятной отчетностью в командной среде и хорошей пригодностью для CI. Существуют компромиссы: охват авто‑фикса может быть менее широким, чем у PHP‑CS‑Fixer, для некоторых предпочтений по стилю, и конфигурация ощущается более ориентированной на стандарты, чем на форматирование. PHP_CodeSniffer бесплатен и с открытым исходным кодом.

    Screenshot of prettier.io

    3. Prettier Plugin PHP

    Prettier Plugin PHP приносит философию Prettier в PHP. Если ваш проект уже использует Prettier для JavaScript, TypeScript, CSS, Markdown или JSON, добавление форматирования PHP по той же логике может быть привлекательным. Его главное преимущество — единообразие в репозиториях с несколькими языками. Малые продуктовые команды и фрилансеры полного стека часто предпочитают единый подход к форматированию по стэку, а не отдельные привычки для фронтенда и бэкенда. Основные компромиссы: он менее специфичен для PHP в настройке, чем PHP-CS-Fixer, и может не соответствовать каждому существующему стилю PHP. Prettier и его PHP‑плагин обычно бесплатны и с открытым исходным кодом.

    Screenshot of friendsofphp.org

    4. Встроенный форматтер PhpStorm

    Если ваша команда работает в основном внутри PhpStorm, встроенный форматтер может быть удивительно эффективным. JetBrains предоставляет детальные настройки стиля кода, поддержку инспекций и действия, экономящие время, что делает форматирование в реальном времени бесшовным. Это мощный выбор для разработчиков, которым нужна немедленная обратная связь в редакторе и качественный IDE‑опыт. Однако полагаться только на форматирование в IDE может привести к дрейфу, если не все используют одну версию и настройки, поэтому команды обычно сочетают PhpStorm с CLI‑форматтером в CI. IDE предлагает отличный опыт редактирования, форматирование в реальном времени и детальные настройки, но лучше подходит для команд, стандартизованных на PhpStorm, и требует дисциплины общих настроек, чтобы избежать несогласованности. PhpStorm — платная коммерческая IDE, хотя JetBrains предоставляет пробные версии и программы лицензирования.

    Screenshot of jetbrains.com

    5. Онлайн‑форматтеры PHP

    Онлайн‑инструменты форматирования PHP полезны, когда нужен быстрый очиститель кода, хочется проверить вывод стиля или помочь клиенту или младшему разработчику понять изменения форматирования без настройки локальной среды. Они удобны для одноразовых фрагментов и быстрых экспериментов, но не являются лучшей основой для профессиональных рабочих процессов. Для продакшн‑репозиториев локальные инструменты и те, что интегрируются в CI, гораздо надёжнее, потому что вам нужна версионированная конфигурация, воспроизводимый вывод и контроль приватности, если код является проприетарным или чувствительным. Онлайн‑форматтеры быстры и удобны для небольших фрагментов, не требуют установки и полезны для быстрых экспериментов, но часто не дают гарантий по приватности, версионированию и долгосрочной доступности. Цена варьируется, и многие онлайн‑форматтеры бесплатны с ограниченными гарантиями.

    Сравнение самых популярных вариантов форматтеров PHP

    Для большинства профессиональных случаев решение обычно сводится к PHP-CS-Fixer против PHP_CodeSniffer/phpcbf, а Prettier Plugin PHP вступает в игру, когда репозиторий работает с большим количеством языков. Глобальная разница такова: PHP-CS-Fixer чаще всего лучше как чистый инструмент форматирования, а phpcs + phpcbf чаще лучше как средство обеспечения соблюдения стандартов. Это не означает, что один инструмент заменяет другой во всех конфигурациях. Многие команды запускают форматирование одним инструментом и валидацию — другим.

    ИнструментЛучшее применениеПреимуществоНедостаток
    PHP-CS-FixerКоманды, которым нужен гибкий, автоматизированный форматБогатая настройка правил и сильная авто‑фиксацияТребуется принятие решений по правилам и закрепление версий
    PHP_CodeSniffer + phpcbfКоманды, соблюдающие формальные стандарты в CIСильная отчётность и проверки стандартовАвто‑исправления могут быть менее гибкими для некоторых стилей
    Prettier Plugin PHPСмешанные репозитории JS/PHPСогласование форматирования между языкамиМеньше PHP‑специфичной настройки
    PhpStorm FormatterIDE‑центрированные рабочие процессыОтличный локальный опыт разработкиНужна CLI/CI‑поддержка для согласованности команды
    Online FormattersБыстрая очистка фрагментовМгновенное удобствоНе подходит для серьёзных рабочих процессов команды

    Выбор подходящего форматтера для вашего проекта

    Лучший PHP‑форматтер — тот, который ваша команда будет использовать стабильно. Это кажется очевидным, но во многих проектах выбирают мощный инструмент, не доводят конфигурацию до конца или не подключают его к Git и CI. Если вы один разработчик или фрилансер, PHP-CS-Fixer часто является самым простым и надёжным выбором, потому что его легко автоматизировать, он хорошо согласуется с PSR-12 и даёт пространство для роста. Если вы работаете в команде, которая уже применяет формальные стандарты кодирования, PHP_CodeSniffer плюс phpcbf может подойти лучше, потому что они объединяют проверку и исправление в рамках соответствия требованиям.

    Что учитывать перед выбором: размер команды влияет на строгость и автоматизацию настройки, существующие руководства по стилю важны, потому что изменение конвенций в зрелом репозитории может привести к шумным диффам, потребности CI важны, потому что локальное форматирование само по себе не обеспечивает согласованность, и размер репозитория имеет значение, потому что производительность и кеширование заметнее в больших монорепозиториях. Зафиксируйте версии форматтера в Composer или настройках инструментов, закоммитьте конфигурацию файла в репозиторий и протестируйте изменения форматирования перед широким развёртыванием. Форматтер должен вселять доверие, а не сюрпризы.

    Пошагово: настройка PHP-CS-Fixer

    PHP-CS-Fixer — отличное место для старта, потому что он хорошо справляется как с простыми, так и с продвинутыми сценариями форматирования. Настройка проста, и как только она внедрена, повседневное использование становится автоматическим.

    Установка через Composer

    Если ваш проект использует Composer, установите его как зависимость для разработки:

    composer require --dev friendsofphp/php-cs-fixer
    

    Вы также можете использовать дистрибутив PHAR, если предпочитаете автономный бинарник, но для команд обычно проще использовать Composer, потому что он закрепляет версию в проекте.

    Создание базовой конфигурации

    Минимальный файл .php-cs-fixer.php с использованием PSR-12 может выглядеть так:

    <?php
    $finder = PhpCsFixerFinder::create()
        ->in(__DIR__ . '/src')
        ->in(__DIR__ . '/tests');
    return (new PhpCsFixerConfig())
        ->setRules([
            '@PSR12' => true,
        ])
        ->setFinder($finder);
    

    Если нужна немного более настраиваемая конфигурация, вы можете расширить её:

    <?php
    $finder = PhpCsFixerFinder::create()
        ->in([__DIR__ . '/src', __DIR__ . '/tests'])
        ->exclude(['vendor', 'storage', 'cache']);
    return (new PhpCsFixerConfig())
        ->setRiskyAllowed(false)
        ->setRules([
            '@PSR12' => true,
            'array_syntax' => ['syntax' => 'short'],
            'ordered_imports' => true,
            'no_unused_imports' => true,
            'trailing_comma_in_multiline' => true,
        ])
        ->setFinder($finder);
    

    Это даёт практическую базу без чрезмерной навязчивости слишком рано.

    Запуск локально и просмотр диффов

    Чтобы исправлять файлы:

    vendor/bin/php-cs-fixer fix
    

    Чтобы предварительно просмотреть изменения с большей наглядностью:

    vendor/bin/php-cs-fixer fix --dry-run --diff
    

    Этот режим dry-run ценен в CI, потому что показывает, соответствует ли код правилам, не переписывая файлы в конвейере.

    Добавление pre-commit hook

    Простой Git pre-commit hook может остановить попадание неотформатированного PHP в репозиторий:

    #!/bin/sh
    vendor/bin/php-cs-fixer fix --quiet
    git add .
    

    В зрелом процессе работы часто ограничивают область до этапированных PHP‑файлов, но даже базовый хук может существенно повысить согласованность.

    Пример GitHub Actions

    Для GitHub Actions простая проверка форматирования может выглядеть так:

    name: PHP Formatting
    on: [push, pull_request]
    jobs:
    ### php-cs-fixer:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: shivammathur/setup-php@v2
    ### with:
              php-version: '8.2'
          - run: composer install --no-interaction --prefer-dist
          - run: vendor/bin/php-cs-fixer fix --dry-run --diff
    

    GitLab CI

    Для GitLab CI эквивалент так же прям:

    php_cs_fixer:
      image: php:8.2
    ### script:
        - apt-get update && apt-get install -y git unzip
        - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
        - php composer-setup.php
        - php composer.phar install --no-interaction --prefer-dist
        - vendor/bin/php-cs-fixer fix --dry-run --diff
    

    Используйте кеширование, если ваш проект большой. На больших репозиториях это может заметно снизить время повторных запусков.

    Screenshot of github.com

    Пошагово: использование PHP_CodeSniffer и phpcbf

    Если PHP-CS-Fixer кажется форматтер‑первым, PHP_CodeSniffer ощущается как инструмент обеспечения стандартов. Это не слабость — во многих организациях именно так и задумано.

    Установка и базовые проверки

    Установите через Composer:

    composer require --dev squizlabs/php_codesniffer
    

    Запустите базовую проверку PSR-12:

    vendor/bin/phpcs --standard=PSR12 src tests
    

    Если нарушения можно автоматически исправить, используйте phpcbf:

    vendor/bin/phpcbf --standard=PSR12 src tests
    

    Создание своей правила

    Простой phpcs.xml или ruleset.xml файл обеспечивает повторяемое применение стандартов:

    <?xml version="1.0"?>
    <ruleset name="ProjectStandard">
        <description>Project coding standard</description>
        <rule ref="PSR12" />
        <exclude-pattern>vendor/*</exclude-pattern>
        <exclude-pattern>storage/*</exclude-pattern>
    </ruleset>
    

    Как только этот файл существует, обычно можно запускать phpcs, не повторяя всю стандартную дефиницию в команде.

    Интеграция в редакторы и CI

    Большинство редакторов может вызывать phpcs напрямую, что полезно для мгновенной обратной связи. В CI phpcs хорошо работает как врата, потому что он завершается с ненулевым статусом при обнаружении нарушений. Это упрощает блокировку неотформатированного кода перед слиянием. Главная ограниченность в том, что phpcbf не исправляет каждое нарушение, которое может обнаружить phpcs. Именно поэтому многие команды предпочитают PHP-CS-Fixer для форматирования и phpcs для отчетности.

    Интеграция редактора и IDE: рабочие процессы форматирования в реальном времени

    Лучшая настройка форматирования — такая, о которой разработчики почти не замечают, потому что она происходит автоматически. Именно здесь важна интеграция редактора. Если форматирование происходит только в CI, разработчики ощущают перебой. Если оно происходит в редакторе с той же конфигурацией, что и в CI, процесс кажется естественным.

    В PhpStorm можно настроить встроенные правила стиля кода и интегрировать внешние инструменты, такие как PHP-CS-Fixer или PHP_CodeSniffer. В VS Code популярные расширения поддерживают phpcs, php-cs-fixer и даже Prettier Plugin PHP. Ключевой момент — консистентность: ваш редактор должен использовать тот же инструмент, ту же версию и ту же конфигурацию проекта, что и ваши окружения командной строки и CI.

    Конфликты обычно возникают, когда несколько инструментов пытаются форматировать один и тот же файл при сохранении. Например, настройки стиля PhpStorm могут конфликтовать с PHP-CS-Fixer, или Prettier может повторно отформатировать файлы после работы phpcbf. Если действия при сохранении кажутся непредсказуемыми, выберите один основной форматтер для каждого типа файла и отключите перекрывающееся поведение форматирования при сохранении.

    Лучшие практики и договорённости в команде

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

    Для наследуемых проектов избегайте мгновенного изменения всего кода за одну ночь, если только вы специально не запланировали это. Более чистый подход — создать отдельный коммит форматирования, быстро слить его и попросить команду потом перебирать ветку. Другой вариант — пошаговое внедрение, когда требования к форматтеру применяются только к тронутым файлам. Оба варианта допустимы. Правильный подход зависит от размера репозитория, координации в команде и давления релиза.

    Сфокусируйте обзор кода на логику. Если форматтер выполняет свою работу, рецензенты не должны тратить время на изменение пробелов. Это реальная продуктивность.

    Общие проблемы и как их избегать

    Главная жалоба на любой PHP‑форматтер — churn в PR. Ветка с небольшой фичей может резко превратиться в сотни изменений только по форматированию, что усложняет обзор. Исправление: дисциплина процесса — сделайте одну базовую проходку форматирования в отдельном коммите, затем отделите работу над фичей.

    Конфликт инструментов — ещё одна частая проблема. Если ваш форматтер и линтер расходятся, разработчики быстро теряют доверие. Совмещайте стандарты, по возможности сокращайте перекрытие и тестируйте полный рабочий процесс перед внедрением в CI.

    Производительность может стать проблемой в больших репозиториях. Используйте кеширование, ограничивайте прогоны на изменённых файлах в локальных хуках и резервируйте полную проверку репозитория для CI или запланированных проверок. Если авто‑фиксовое изменение повлечёт изменение поведения, остановитесь и проверьте. Форматирование не должно менять логику, но некоторые рискованные фиксаторы могут вызывать побочные эффекты. Поэтому тесты должны запускаться перед слиянием.

    Краткий справочник: команды, фрагменты конфигурации и шаблоны CI

    Ниже перечислены наиболее полезные команды для повседневной работы:

    ЗадачаКоманда
    Запуск PHP-CS-Fixervendor/bin/php-cs-fixer fix
    Предпросмотр изменений PHP-CS-Fixervendor/bin/php-cs-fixer fix --dry-run --diff
    Запуск phpcs с PSR-12vendor/bin/phpcs --standard=PSR12 src tests
    Авто‑исправление phpcbfvendor/bin/phpcbf --standard=PSR12 src tests

    Практичная настройка для многих команд проста: используйте PHP-CS-Fixer для форматирования, по желанию применяйте phpcs для обеспечения соблюдения и отчетности, подключите оба к хукам pre-commit и CI, и храните конфигурацию в репозитории.

    Часто задаваемые вопросы

    Изменяет ли форматирование поведение кода?

    Обычно нет. Правильный PHP‑форматировщик предназначен для сохранения поведения кода при изменении стиля. Тем не менее некоторые продвинутые фиксаторы могут быть более агрессивными, поэтому разумно запускать тесты после внедрения новых правил.

    Стоит ли запускать форматтер в CI или локально?

    И то, и другое. Локальное форматирование даёт разработчикам мгновенную обратную связь. CI обеспечивает команду финальной проверкой единообразия. Использование обоих подходов предотвращает сюрпризы.

    Как работать с репозиториями с несколькими языками?

    Если ваш репозиторий содержит PHP плюс JavaScript, CSS, Markdown и JSON, разделённый подход работает хорошо. Используйте отдельный PHP‑форматтер для PHP и Prettier для фронтенд‑ресурсов, или применяйте Prettier Plugin PHP, если кросс‑языковая консистентность важнее глубокой PHP‑специфической настройки.

    Как насчет споров по стилю кодирования?

    Именно для этого нужен форматтер. Примите решение один раз, настройте инструмент и переходите к обзору архитектуры, корректности и поддерживаемости.

    Дополнительные ресурсы и ссылки

    Официальная документация по-прежнему остаётся лучшим местом для проверки поддержки правил, деталей установки и текущей совместимости синтаксиса. Начните с PHP-CS-Fixer на GitHub, PHP_CodeSniffer на GitHub, документации PhpStorm на jetbrains.com и Prettier на prettier.io.

    Если вы внедряете форматтер для команды сегодня, наиболее эффективный следующий шаг прост: выберите один инструмент, зафиксируйте конфигурацию проекта, запустите его на небольшой части кода и подключите к своему редактору и CI. Как только это заработает без сбоев, расширяйте область. Надёжный PHP‑форматировщик не просто очищает код, он очищает весь процесс разработки.