Цель статьи — помочь разработчикам которые много слышали про статический анализ, но пока что так и не поняли что это такое и с чем его едят.

Статический анализ

Анализ программного обеспечения, производимый без реального выполнения исследуемых программ, процесс выявления ошибок и недочетов в исходном коде программ. Список языков для которых существуют статические анализаторы кода достаточно велик, например это Си, Си++, C#, Java, Ada, Fortran, Perl, Ruby и т. д. Компиляторы различных языков программирования во время своей работы так же запускают статические анализаторы (как правило усеченные версии) которые находят ошибки. Т.о. использование статического анализа, в поиске ошибок, приближает/приравнивает PHP к компилируемым языкам программирования.

Сообщество PHP прикладывает значительные усилия в сторону развития статического анализа, так типы mixed и never были добавлены для лучшего анализа программами статического анализа.

Необходимость статического анализа

Статический анализ позволяет найти уйму различных проблем в коде, начиная от неправильного использования конструкций языка, заканчивая опечатками. При проведении code review позволяет сосредоточиться на просмотре реализации логики программы, а не на поиске синтаксических ошибок, опечаток, ошибок в данных, мертвый код и т. п.

Задачи, решаемые программами статического анализа кода:

  • Выявление ошибок в программах.

  • Рекомендации по оформлению кода.

  • Подсчет метрик.

Преимущества статического анализа кода:

  • Полное покрытие кода. Статические анализаторы проверяют даже те фрагменты кода, которые получают управление крайне редко.

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

  • Можно легко и быстро обнаруживать опечатки и последствия использования Copy-Paste.

Недостатки статического анализа кода:

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

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

Какой анализатор выбрать?

На данный вопрос однозначного ответа нет! Дело в том, что инструменты статического анализа постоянно развиваются и если сегодня один анализатор впереди планеты всей, то завтра он может быть последним. Например компания Badoo в своей статье пишут о том, что они используют сразу три статических анализатора. В сообществе PHP большую популярность получил Psalm, но мой выбор пал на PHPStan и связано это с количеством спонсоров у проекта.

Автоматизация

Запуск программ статического анализа возможно добавить в процесс CI (CI/CD), тем самым не допустить попадания некачественного кода в общую ветку разработки.

Пример (не панацея) bash скрипта:

#!/bin/bash
vendor/bin/phpstan analyse -c phpstan.neon
 
if [ $? -eq 0 ]
then
  echo "Successful checks PHPStan"
  exit 0
else
  echo "ERRORS script PHPStan" >&2
  exit 1
fi

PHPStan

Оф. сайт

GitHub

Ниже опишу простые примеры использования инструмента. За более подробной информацией обращайтесь к страницам официальной документации!

Установка:

composer require --dev phpstan/phpstan

Запуск:

vendor/bin/phpstan analyse [options] [--] [<paths>...]

example:
vendor/bin/phpstan analyse -l 5 -c phpstan.neon ./src/

Настройка PHPStan

Все опции запуска PHPStan можно вынести в файл конфигурации phpstan.neon и запускать скрипт следующим образом:

vendor/bin/phpstan analyse -c phpstan.neon

Пример файла конфигурации PHPStan:

parameters:
    level: 5
    paths:
        - src

Уровни анализа (-l | --level)

*оставил без перевода, т.к. боюсь неправильно донести их смысл.

*уровень по умолчанию 0, т.е. если в параметрах запуска не указать уровень, то будет выбран уровень 0

Уровень 0: basic checks, unknown classes, unknown functions, unknown methods called on $this, wrong number of arguments passed to those methods and functions, always undefined variables.

Уровень 1: possibly undefined variables, unknown magic methods and properties on classes with __call and __get.

Уровень 2: unknown methods checked on all expressions (not just $this), validating PHPDocs.

Уровень 3: return types, types assigned to properties.

Уровень 4: basic dead code checking - always false instanceof and other type checks, dead else branches, unreachable code after return; etc.

Уровень 5:  checking types of arguments passed to methods and functions.

Уровень 6: report missing typehints

Уровень 7: report partially wrong union types - if you call a method that only exists on some types in a union type, level 7 starts to report that; other possibly incorrect situations

Уровень 8: report calling methods and accessing properties on nullable types

Уровень 9: be strict about the mixed type - the only allowed operation you can do with it is to pass it to another mixed

Важно

PHPStan при своем запуске во многом ориентируется на typehints, но большей частью проверки операются на PHPDocs!

Несколько примеров PHPDocs

Проверка полей массива (если вы их используете):

/**
 * ......
 * @param array{roles: array, name: string, login: string, password: string} $data
 * ......
 */

Проверка поля класса:

use App\...\Roles;
 
// ......
 
/**
 * @var Roles[] - пример массива объектов типа Roles
 */
private array $roles;

Проверка возвращаемого функцией результата:

use App\...\Roles;
 
// .....
 
/**
 * .....
 * @return Roles - пример возвращаемого результата
 */
function fn(): Roles;

Комментарии (8)


  1. gmtd
    00.00.0000 00:00
    +1

    А интеграция с вс код и другими редакторами есть?


    1. snegprog Автор
      00.00.0000 00:00

      PHPStan можно интегрировать с PHPStorm, как это сделать лучше читать документацию к данной IDE. С вс код вероятно тоже есть интеграция, но точно ничего не скажу.


  1. des1roer
    00.00.0000 00:00

    против https://github.com/VKCOM/noverify phpstan ужасно медленный


    1. snegprog Автор
      00.00.0000 00:00
      +1

      Спасибо за подсказку, людям больше выбора, тоже посмотрю в эту сторону.


    1. positron48
      00.00.0000 00:00

      А есть какая-то информация по качественному сравнению? Находит ли noverify то, что не находит phpstan и наоборот?

      Умеет ли подгружать исходники, не требующие статической проверки (условно - нужно проверить, правильно ли мы используем фреймворк, но сам фреймворк проверять не нужно)? Нашел: --index-only-files


      1. des1roer
        00.00.0000 00:00
        +1

        https://www.youtube.com/watch?v=FQijPdVAnQw возможно будет полезно


  1. waleev
    00.00.0000 00:00
    +2

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


    1. snegprog Автор
      00.00.0000 00:00

      Цель статьи дать направление и вкратце рассказать для чего статические анализаторы вообще нужны.