Начиная с Laravel 9, превосходный Laravel Pint поставляется в комплекте с новой установкой Laravel. Я люблю Pint, и для большинства людей достаточно использовать его для форматирования в стиле кода. До Laravel Pint я предпочитал комбинацию PHP CS Fixer и PHP Codesniffer — оба превосходны в тандеме и предлагают уникальные правила, которые могут помочь обеспечить стиль кода.
Стиль длины строки является одним из примеров того, где PHP Codesniffer может дополнять такие инструменты, как PHP CS Fixer, и мы можем использовать оба, чтобы помочь разработчикам придерживаться согласованного стиля кода. Если вы используете PSR-12, в разделе «Линии» содержится следующая информация о длине
строки:Не должно быть жесткого ограничения на длину строки.
Мягкое ограничение на длину строки ДОЛЖНО составлять 120 символов.
Строки НЕ ДОЛЖНЫ быть длиннее 80 символов; строки длиннее этого ДОЛЖНЫ быть разделены на несколько последующих строк не более 80 символов каждая.
Наши инструменты CI могут применять как мягкие, так и жесткие ограничения длины строки, но я интерпретирую PSR-12 так, что PHP Codesniffer должен предупреждать нас и не возвращать никаких ошибок для строк длиной > 80
. Об этом мы расскажем далее в статье.
Давайте поработаем над настройкой PHP Codesniffer в новом проекте Laravel, а затем в последующих учебниках мы узнаем, как создать пользовательский стандарт PHP Codesniffer, который мы можем использовать во всех наших проектах.
По пути я покажу вам некоторые настройки конфигурации, которые мне нравится устанавливать, чтобы получить максимальную отдачу от PHP Codesniffer во время разработки.
Установка
Первое, что мы сделаем, это создадим пример проекта, чтобы вы могли увидеть, как включить PHP Codesniffer с Laravel с нуля:
laravel new phpcs-part-1 --git
cd phpcs-part-1
флаг git установит новое приложение Laravel, инициализирует git и зафиксирует все в контроле версий. Это оставляет нам чистый лист, чтобы увидеть изменения, которые мы вносим в этот учебник.
Далее, давайте установим PHP Codesniffer в качестве зависимости разработки
composer require --dev squizlabs/php_codesniffer
: Примечание: На момент написания статьи требуемая команда устанавливает версию ^3.7
, но ваша версия может немного отличаться, что не является проблемой.
Если вы запустите phpcs
из командной строки, вы увидите, что он хочет, чтобы вы указали путь:
$ vendor/bin/phpcs
ERROR: You must supply at least one file or directory to process.
Run "phpcs --help" for usage information
Не волнуйтесь, мы собираемся добавить файл конфигурации, чтобы указать, какие пути PHPCS должен включать (и исключать), но если вы запустите его с набором правил по умолчанию (Pear), вы получите кучу ошибок с установкой Laravel по умолчанию:
$ vendor/bin/phpcs -v app
Registering sniffs in the PEAR standard... DONE (28 sniffs registered)
....
FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Providers/AppServiceProvider.php
--------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 2 LINES
--------------------------------------------------------------------------------
2 | ERROR | Missing file doc comment
7 | ERROR | Missing doc comment for class AppServiceProvider
--------------------------------------------------------------------------------
Если вы проверите код выхода, вы увидите, что ошибки заставляют PHPCS выходить с ненулевым кодом
$ echo $?
2
: я хочу прояснить: эти ошибки не потому, что наш код имеет плохое форматирование (совсем наоборот), а потому, что мы используем стандарт PEAR по умолчанию, которому Laravel не следует из коробки.
Давайте рассмотрим использование другого стандарта и создание конфигурационного файла.
Прежде чем мы добавим файл конфигурации в наш проект, давайте посмотрим, как будет выглядеть та же конфигурация с помощью командной строки. Мы знаем, что мы не хотим использовать стандарт PEAR, поэтому давайте сначала выполним нашу команду PHPCS со встроенным стандартом PSR-12:
vendor/bin/phpcs --standard=PSR12 app
Если вы внимательно посмотрите на выходные данные, вы заметите, что стандарт PSR12 для PHP Codesniffer хочет исправить некоторые интервалы вокруг сцепленных строк:
FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php
----------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 1 LINE
----------------------------------------------------------------------
28 | ERROR | [x] Expected at least 1 space before "."; 0 found
28 | ERROR | [x] Expected at least 1 space after "."; 0 found
----------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------
X
означает, что мы можем автоматически исправлять эти сниффы (не все SNIFF PHP Codsniffer автоматически исправляются) с помощью корзины phpcbf
, которая поставляется с Codesniffer. Мы вернемся к этому через секунду.
Во-первых, давайте посмотрим на несколько других флагов команд, которые я предпочитаю использовать. Как только вы начнете использовать PHP Codesniffer в разработке и CI, я замечаю, что полное имя sniff не очевидно. Возможно, вы захотите настроить этот запах, игнорировать его на определенной строке и т. Д.
Чтобы всегда видеть полный sniff в командной строке, вы можете использовать флаг '-s':
vendor/bin/phpcs -s --standard=PSR12 app
Вот пример того, как выглядит вывод с полным sniff:
FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php
----------------------------------------------------------------------------------------------------------------
FOUND 2 ERRORS AFFECTING 1 LINE
----------------------------------------------------------------------------------------------------------------
28 | ERROR | [x] Expected at least 1 space before "."; 0 found
| | (PSR12.Operators.OperatorSpacing.NoSpaceBefore)
28 | ERROR | [x] Expected at least 1 space after "."; 0 found
| | (PSR12.Operators.OperatorSpacing.NoSpaceAfter)
----------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 2 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------------------------------------------------
Вы можете увидеть PSR12. Operators.OperatorSpacing.NoSpaceBefore
sniff найден в приведенном выше примере. Если мы хотим проигнорировать этот перехват в файле Kernel.php
, мы можем добавить его в файл app/Console/Kernel.php
вокруг строки 28:
// phpcs:disable PSR12.Operators.OperatorSpacing.NoSpaceAfter
$this->load(__DIR__.'/Commands');
// phpcs:enable
Если мы перезапустим команду — на этот раз для файла Kernel.php
— мы увидим, что правило NoSpaceAfter
отключено для этой строки, но мы все равно получим ошибку NoSpaceBefore
:
vendor/bin/phpcs -s --standard=PSR12 app/Console/Kernel.php
FILE: /Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php
----------------------------------------------------------------------------------------------------------------
FOUND 1 ERROR AFFECTING 1 LINE
----------------------------------------------------------------------------------------------------------------
29 | ERROR | [x] Expected at least 1 space before "."; 0 found
| | (PSR12.Operators.OperatorSpacing.NoSpaceBefore)
----------------------------------------------------------------------------------------------------------------
PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
----------------------------------------------------------------------------------------------------------------
Мы можем отключить несколько правил для заданного набора строк, разделив сниффы запятыми следующим образом:
// phpcs:disable PSR12.Operators.OperatorSpacing.NoSpaceAfter, PSR12.Operators.OperatorSpacing.NoSpaceBefore
$this->load(__DIR__.'/Commands');
// phpcs:enable
Наконец, давайте отменим все изменения, внесенные в файл app/Console/Kernel.php
. Вы обнаружите, что эти два правила, которые мы использовали в качестве примера, напрямую конфликтуют с Laravel Pint, которая ожидает пробелы до и после.
Во-первых, давайте автоматически исправим вышеуказанные сниффы с помощью phpcbf
:
vendor/bin/phpcbf --standard=PSR12 app
PHPCBF RESULT SUMMARY
----------------------------------------------------------------------------------------------
FILE FIXED REMAINING
----------------------------------------------------------------------------------------------
/Users/paul/code/sandbox/phpcs-part-1/app/Models/User.php 1 0
/Users/paul/code/sandbox/phpcs-part-1/app/Http/Controllers/Controller.php 1 0
/Users/paul/code/sandbox/phpcs-part-1/app/Console/Kernel.php 2 0
----------------------------------------------------------------------------------------------
A TOTAL OF 4 ERRORS WERE FIXED IN 3 FILES
----------------------------------------------------------------------------------------------
После этого давайте запустим Laravel Pint, чтобы увидеть, как он делает обратное тому, что PHP Codesniffer исправил автоматически:
$ vendor/bin/pint
FIXED 54 files, 1 style issue fixed
✓ app/Console/Kernel.php concat_space
Чтобы мы могли использовать оба инструмента во время разработки и в средах CI, нам нужно выбрать стиль и применить его с помощью одного инструмента и отключить его от другого. Я предпочитаю автоматические исправления от Pint, поэтому я отключаю конкурирующий Sniff в PHP Codesniffer.
Файл конфигурации
Давайте разрешим конфликт между Pint и Codesniffer, создав файл конфигурации. В приложении я обычно создаю файл phpcs.xml
, но если вы планируете позволить другим использовать ваше приложение в качестве отправной точки, вы можете рассмотреть возможность использования phpcs.xml.dist
. Давайте создадим его как phpcs.xml
:
<?xml version="1.0"?>
<!-- @see https://pear.php.net/manual/en/package.php.php-codesniffer.annotated-ruleset.php -->
<ruleset name= "Laravel PHPCS Rules">
<description>PHPCS ruleset for Example app.</description>
<file>tests</file>
<file>app</file>
<!-- Show progress of the run -->
<arg value= "p"/>
<!-- Show sniff codes in all reports -->
<arg value= "s"/>
<!-- Our base rule: set to PSR12 -->
<rule ref="PSR12">
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceBefore"/>
<exclude name="PSR12.Operators.OperatorSpacing.NoSpaceAfter"/>
</rule>
<rule ref= "Generic.Files.LineLength">
<properties>
<property name="lineLimit" value="80"/>
<property name="absoluteLineLimit" value="120"/>
</properties>
</rule>
<rule ref="PSR1.Methods.CamelCapsMethodName.NotCamelCaps">
<exclude-pattern>tests/</exclude-pattern>
</rule>
</ruleset>
Вы можете видеть, что я добавил наш аргумент -s
в конфигурацию, поэтому все отчеты показывают коды sniff. Мы также ориентируемся на каталоги приложений
и тестов,
но не стесняйтесь настраивать другие каталоги в вашем проекте, которые вы хотите, чтобы Codesniffer проверил.
Мы отключили сниффы интервалов оператора, поэтому Пинт должен быть доволен, и PHP Codesniffer теперь будет игнорировать эти правила.
Мы также настроили правило длины строки, используя язык PSR-12 в качестве руководства для ограничения и максимального значения строки. Эти перехваты сообщаются как предупреждения, поэтому при запуске этого инструмента в CI вы должны убедиться, что либо предупреждения подавлены, либо CI по-прежнему передается с предупреждениями. Предупреждения предназначены для того, чтобы помочь вам, разработчику, исправить длины строк в разработке.
Наконец, sniff NotCamelCaps
исключен из папки tests
, потому что мне нравится писать тесты PHPUnit со змеиным регистром:
/* @test */
public function it_does_something_awesome()
теперь мы можем запускать phpcs
без каких-либо аргументов, и он подберет наш конфигурационный файл. Вы должны видеть только предупреждения о длине строки и многократном импорте.
vendor/bin/phpcs
Еще одно нарушение, которое вы заметите, это снифф MultipleImport
, который связан с этой строкой, например:
class User extends Authenticatable
{
use HasApiTokens, HasFactory, Notifiable;
// ...
}
Не стесняйтесь отключить этот sniff, если хотите, или вы можете автоматически исправить его (используя наш конфигурационный файл) с помощью командной строки phpcbf
bin:
vendor/bin/phpcbf
.........F..........F.. 23 / 23 (100%)
PHPCBF RESULT SUMMARY
----------------------------------------------------------------------------------------------
FILE FIXED REMAINING
----------------------------------------------------------------------------------------------
/Users/paul/code/sandbox/phpcs-part-1/app/Models/User.php 1 0
/Users/paul/code/sandbox/phpcs-part-1/app/Http/Controllers/Controller.php 1 0
----------------------------------------------------------------------------------------------
A TOTAL OF 2 ERRORS WERE FIXED IN 2 FILES
----------------------------------------------------------------------------------------------
Заключение
Мы рассмотрели довольно много земли, но вы должны быть в состоянии начать использовать PHP Codesniffer с нуля с Laravel. Это может быть отличным дополнением, если вы хотите нацелиться на некоторые из конкретных правил, которые PHP CS Fixer не выполняет, и я снабдил вас тем, как отключить конфликтующие правила или правила, которые вы хотите отключить.