Анализ кода - PHPStan
Статический анализ кода
Анализ исходного кода проводится для выявления синтаксических и логических ошибок без запуска всего приложения (как написано на PHPStan: анализатор найдет ошибки в вашем коде без написания тестов ). Такой процесс обычно делают перед запуском тестов.
Таких анализаторов достаточно много, например: PHPStan, PSALM
Здесь мы рассмотрим PHPStan. Модуль требует версию php >=7.2.
Установка
Установить phpstan в ваш проект вы можете используя composer.
composer require --dev phpstan/phpstan
Исполняемый файл будет лежать в vendor/bin .
Или вы можете скачать phar файл с официального сайта проекта. Подробнее: https://phpstan.org/user-guide/getting-started
Запуск
Запустим анализ нашего кода в директории src
vendor/bin/phpstan analyse src
У консольной команды есть несколько опций. Вот наиболее часто используемые опции:
- --level|-l - уровень анализа кода(см. ниже);
- --configuration|-c - путь до файла конфигурации(см. ниже);
- --memory-limit - максимальное количество используемой памяти, имеет такой формат записи как в php.ini (--memory-limit 1G);
- --error-format - формат вывода ошибок (table, json и другие ).
Очистка кэша:
vendor/bin/phpstan clear-result-cache [options]
Уровни проверки
Всего уровней 10: от 0 (самый свободный) до 9 (самый строгий).
- 0 - базовые проверки, неизвестные классы, неизвестные функции, неизвестные методы, вызываемые с помощью $this, неправильное количество аргументов, передаваемых этим методам и функциям, всегда неопределенные переменные
- 1 - возможные неопределенные переменные, неизвестные магические методы и свойства в классах с __call и __get
- 2 - неизвестные методы проверяются для всех выражений (не только для $this ), проверяя PHPDocs
- 3 - возвращаемые типы, типы, присвоенные свойствам
- 4 - базовая проверка мертвого кода - всегда ложные проверки instanceof и других типов, мертвые ветви else, недоступный код после возврата; и т.д.
- 5 - проверка типов аргументов, передаваемых методам и функциям
- 6 - сообщить о пропущенных типографских указателях
- 7 - сообщать о частично неправильных типах объединения - если вы вызываете метод, который существует только для некоторых типов в типе объединения, уровень 7 начинает сообщать об этом; другие возможные некорректные ситуации
- 8 - сообщать о вызове методов и доступе к свойствам для типов с возможностью обнуления
- 9 - будьте строги в отношении смешанного типа - единственная разрешенная операция, которую вы можете с ним выполнить, - это передать его другому смешанному типу
Каждый последующий уровень включает в себя все предыдущие.
Конфигурирование
Для конфигурирования анализатора используется файл phpstan.neon. Пример phpstan.neon:
parameters:
level: 1
scanDirectories: # какие директории просканировать дополнительно
- %currentWorkingDirectory%/bin/.phpunit
paths: # пути для анализа
- %currentWorkingDirectory%/src
- %currentWorkingDirectory%/tests
reportUnmatchedIgnoredErrors: false
fileExtensions:
- php
excludePaths: # исключить директории из анализа
analyse:
- src/thirdparty
analyseAndScan:
- src/broken
Подробнее о конфигурационном файле: https://phpstan.org/config-reference
Baseline
Baseline (базовая линия) - игнорирование текущих ошибок. Например, на текущий момент у вас есть какие то незначительные ошибки при проверки анализатора, они не влияют на работу приложения и времени на исправление у вас нет. Для скрытия этих ошибок вы можете запустить анализ с опцией --generate-baseline
vendor/bin/phpstan analyse --configuration phpstan.neon --generate-baseline
Результатом работы скрипта будет файл phpstan-baseline.neon , в котором будут описаны текущие ошибки. Примерно так:
parameters:
ignoreErrors:
-
message: "#^Only numeric types are allowed in pre\\-decrement, bool\\|float\\|int\\|string\\|null given\\.$#"
count: 1
path: src/Analyser/Scope.php
-
message: "#^Anonymous function has an unused use \\$container\\.$#"
count: 2
path: src/Command/CommandHelper.php
Подробнее о baseline: https://phpstan.org/user-guide/baseline Подробнее об игнорировании ошибок: https://phpstan.org/user-guide/ignoring-errors
Игнорирование ошибок в коде:
@phpstan-ignore-line - phpsan игнорируют все ошибки на текущей строке
`
php
echo $foo; / @phpstan-ignore-line */
`
- @phpstan-ignore-next-line - phpsan игнорируют все ошибки на следующей строке
/** @phpstan-ignore-next-line */ echo $foo;
- с версии 1.11.0 доступны множественные ошибки. Их можно игнорировать с помощью идентификаторов, разделенных запятыми. Множественные ошибки с одним и тем же идентификатором также можно игнорировать таким же образом:
echo $foo, $bar; // @phpstan-ignore variable.undefined, variable.undefined
Свойства PHPDocs
в версии 1.10.26 доступны следующие теги
private const POSSIBLE_PHPSTAN_TAGS = [
'@phpstan-param',
'@phpstan-param-out',
'@phpstan-var',
'@phpstan-extends',
'@phpstan-implements',
'@phpstan-use',
'@phpstan-template',
'@phpstan-template-contravariant',
'@phpstan-template-covariant',
'@phpstan-return',
'@phpstan-throws',
'@phpstan-ignore-next-line',
'@phpstan-ignore-line',
'@phpstan-method',
'@phpstan-pure',
'@phpstan-impure',
'@phpstan-immutable',
'@phpstan-type',
'@phpstan-import-type',
'@phpstan-property',
'@phpstan-property-read',
'@phpstan-property-write',
'@phpstan-consistent-constructor',
'@phpstan-assert',
'@phpstan-assert-if-true',
'@phpstan-assert-if-false',
'@phpstan-self-out',
'@phpstan-this-out',
'@phpstan-allow-private-mutation',
'@phpstan-readonly',
'@phpstan-readonly-allow-private-mutation'
];
Подробнее о всех свойствах: https://phpstan.org/writing-php-code/phpdoc-types
Файлы заглушки
Если в /vendor не корректный PHPDoc, то нам предлагают сделать stub-file с правильным PHPDoc, пространство имен и имена классов/интерфейсов/признаков/методов/функций должны совпадать с исходным кодом, который вы описываете. Тела методов могут оставаться пустыми, PHPStan интересуют только PHPDocs. Заглушки могут иметь любое расширение файла. Можно именовать .stub вместо .php , чтобы заглушки не путали вашу IDE. Файл-заглушка должен быть добавлен к ключу stubFiles в файле конфигурации:
parameters:
stubFiles:
- stubs/Foo.stub
- stubs/Bar.stub
Подробнее: https://phpstan.org/user-guide/stub-files