Перейти к содержанию

Обзор правил

Qualimetrix содержит набор встроенных правил для проверки качества PHP-кода. Каждое правило анализирует определённый аспект кода -- сложность, размер, связанность, проектирование, поддерживаемость или распространённые плохие практики -- и сообщает о нарушениях при превышении пороговых значений.

Идентификаторы правил и судимые метрики

Идентификатор правила и ключ метрики -- это два имени из двух словарей, и они не одно и то же даже там, где выглядят похоже. Идентификатор правила -- complexity.ccn -- это то, что настраивают, подавляют и перенастраивают. Ключ метрики -- complexity.ccn -- это измеренное число, которое правило сравнивает со своими порогами.

Там, где правило берёт своё число из каталога метрик, раздел правила на странице группы называет его как Судимая метрика, сразу под идентификатором правила; ту же пару печатает bin/qmx rules. Правила, публикующие величину собственного изготовления -- размер цикла, число сработавших критериев, -- не называют метрики, и вывод команды тоже.

Уровни серьёзности

Каждое нарушение имеет один из двух уровней серьёзности:

  • Warning (предупреждение) -- код становится сложнее в поддержке. Стоит задуматься о рефакторинге, но ситуация пока не критична.
  • Error (ошибка) -- код перешёл порог, за которым вероятны реальные проблемы: баги, трудности с тестированием или сопротивление изменениям. Требуется внимание.

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

Сводная таблица правил

Правила сложности

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

Правило ID Что проверяет Warning Error
Цикломатическая сложность complexity.ccn Количество путей принятия решений в методе 10 (метод) 20 (метод)
Когнитивная сложность complexity.cognitive Насколько трудно понять код 15 (метод) 30 (метод)
NPath-сложность complexity.npath Общее количество возможных путей выполнения 200 (метод) 1000 (метод)
WMC complexity.wmc Суммарная сложность всех методов класса 50 80

Подробнее о правилах сложности -->

Правила размера

Эти правила проверяют, не разрослись ли ваши классы и пространства имён. Большие классы, как правило, делают слишком много всего сразу.

Правило ID Что проверяет Warning Error
Количество методов size.method-count Число методов в классе 20 30
Количество классов size.class-count Число классов в пространстве имён 15 25
Количество свойств size.property-count Число свойств в классе 15 20

Подробнее о правилах размера -->

Правила проектирования

Эти правила проверяют глубину наследования, покрытие типами и структурные проблемы.

Правило ID Что проверяет Warning Error
Глубина наследования design.dit Глубина цепочки наследования 4 6
NOC design.noc Количество классов, наследующих от данного 10 15
Покрытие типами параметров design.type-coverage.param Процент типизированных параметров 80% (ниже) 50% (ниже)
Покрытие типами возврата design.type-coverage.return Процент типизированных возвращаемых значений 80% (ниже) 50% (ниже)
Покрытие типами свойств design.type-coverage.property Процент типизированных свойств 80% (ниже) 50% (ниже)
Data-класс design.data-class Публичный интерфейс в основном отдаёт данные, низкая сложность Warning --
God-класс design.god-class Чрезмерно сложные, большие классы с низкой связностью 3+ критерия все критерии

Подробнее о правилах проектирования -->

Правила связности (Cohesion)

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

Правило ID Что проверяет Warning Error
LCOM cohesion.lcom Занимается ли класс слишком многими несвязанными вещами 3 5
Метрика ID Что проверяет Рекомендация
TCC cohesion.tcc Доля пар публичных методов, разделяющих свойства >= 0.5
LCC cohesion.lcc Доля с учётом транзитивных связей >= 0.5

Note

TCC и LCC — это метрики, а не правила. Их нельзя включить или отключить через --disable-rule / --only-rule, и они не генерируют нарушений. В отчётах они отображаются как информационные значения и используются правилом God Class в качестве входных данных. LCOM выше — правило со своими порогами.

Подробнее о правилах связности -->

Правила связанности

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

Правило ID Что проверяет Warning Error
CBO coupling.cbo Общее количество зависимостей 14 20
Нестабильность coupling.instability Насколько класс зависит от других по сравнению с тем, сколько зависят от него 0.8 0.95
Расстояние coupling.distance Баланс между абстрактностью и стабильностью 0.3 0.5
ClassRank coupling.class-rank Критичные узловые классы через алгоритм PageRank 0.02 0.05

Подробнее о правилах связанности -->

Правила поддерживаемости

Правило ID Что проверяет Warning Error
Индекс поддерживаемости maintainability.mi Общая оценка поддерживаемости кода <40 <20

Подробнее о правилах поддерживаемости -->

Правила архитектуры

Правило ID Что проверяет Warning Error
Циклические зависимости architecture.circular-dependency Классы, которые зависят друг от друга по кругу -- Error
Нарушения слоёв architecture.layer-violation Зависимости между слоями, не разрешённые архитектурной политикой -- Warning

Подробнее о правилах архитектуры -->

Правила дублирования

Эти правила обнаруживают дублированные блоки кода по всей кодовой базе с помощью анализа потока токенов.

Правило ID Что обнаруживает Warning Error
Дублирование кода duplication.clone Структурно идентичные блоки кода между файлами < 50 строк >= 50 строк

Подробнее о правилах дублирования -->

Правила запахов кода

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

Правило ID Что обнаруживает
Булевый аргумент code-smell.boolean-argument Параметры типа bool в сигнатурах методов
Count в цикле code-smell.count-in-loop Вызов count() в условии цикла
Отладочный код code-smell.debug-code var_dump, print_r, debug_backtrace и т.д.
Пустой catch code-smell.empty-catch Блоки catch без тела
Подавление ошибок code-smell.error-suppression Оператор подавления ошибок @
Eval code-smell.eval Использование eval()
Exit code-smell.exit Использование exit() или die()
Goto code-smell.goto Использование goto
Суперглобальные переменные code-smell.superglobals Прямой доступ к $_GET, $_POST и т.д.
Длинный список параметров code-smell.long-parameter-list Методы с чрезмерным количеством параметров
Недостижимый код code-smell.unreachable-code Код после return/throw/exit
Идентичные подвыражения code-smell.identical-subexpression Одинаковые операнды, дублирующиеся условия, идентичные ветки тернарного оператора
Избыточная инъекция в конструктор code-smell.constructor-overinjection Слишком много зависимостей в конструкторе
Неиспользуемый private code-smell.unused-private Неиспользуемые приватные методы, свойства, константы

Подробнее о правилах запахов кода -->

Правила безопасности

Эти правила обнаруживают паттерны, которые могут привести к уязвимостям безопасности.

Правило ID Что обнаруживает
Захардкоженные учётные данные security.hardcoded-credentials Пароли, API-ключи, токены в коде
SQL-инъекция security.sql-injection Суперглобальные переменные в SQL-запросах
XSS security.xss Несанитизированные суперглобальные в echo/print
Внедрение команд security.command-injection Суперглобальные переменные в shell-функциях
Чувствительные параметры security.sensitive-parameter Отсутствующий атрибут #[\SensitiveParameter]

Подробнее о правилах безопасности -->

Правила аннотаций

Это правило проверяет сами аннотации @qmx-ignore / @qmx-threshold, написанные в коде, а не код. Оно публикуется через четыре канала — annotation.unresolved-directive, annotation.unsupported-threshold и annotation.invalid-threshold являются ошибками конфигурации и валят прогон безусловно; annotation.unused-directive — обычный долг с настраиваемой severity и единственный канал, который нельзя адресовать @qmx-ignore.

Правило ID Что обнаруживает
Валидация директив annotation.directive Некорректные, неподдерживаемые, неразбираемые или неиспользуемые директивы @qmx-ignore / @qmx-threshold

Подробнее о правилах аннотаций -->

Правила обнаружения файлов (Discovery)

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

Правило ID Что обнаруживает
Непривязанное исключение discovery.unmatched-exclude Паттерн исключения, не убравший ни одного каталога

Подробнее о правилах обнаружения файлов -->

Правила подавления (Suppression)

Это правило сообщает о конфигурации подавлений самого прогона, а не о коде: значение suppress_paths или suppress_namespaces — глобальное или под rules.<имя> — не назвавшее ни одного проанализированного файла и ни одного объявленного неймспейса. Такое значение ничего не прячет и не спрячет, тогда как автор считает, что прячет.

Правило ID Что обнаруживает
Конфигурация подавлений suppression.configuration Значение подавления, не назвавшее ничего из измеренного

Подробнее о правилах подавления -->

Отключение правил

Можно отключить отдельные правила или целые группы:

# Отключить одно правило
bin/qmx check src/ --disable-rule=complexity.npath

# Отключить целую группу (wildcard-сопоставление; захватывает только потомков, не сам "code-smell")
bin/qmx check src/ --disable-rule=code-smell.*

Исключение неймспейсов

Любое правило поддерживает suppress_namespaces для подавления нарушений из конкретных пространств имён (сопоставление по префиксу). Файлы по-прежнему анализируются и метрики собираются, но нарушения не выводятся:

rules:
  complexity.ccn:
    suppress_namespaces:
      - App\Tests
      - App\Legacy
bin/qmx check src/ --rule-opt="complexity.ccn:suppress_namespaces=App\Tests"

Это полезно для тестового кода, сгенерированного кода или legacy-модулей, которые вы хотите сохранить в метриках, но исключить из отчёта о нарушениях для конкретного правила.

Настройка пороговых значений

Переопределение любого порога через командную строку:

bin/qmx check src/ --rule-opt="complexity.ccn:callable.warning=15"
bin/qmx check src/ --rule-opt="size.method-count:warning=25"

Или в конфигурационном файле qmx.yaml:

rules:
  complexity.ccn:
    callable:
      warning: 15
      error: 25
  size.method-count:
    warning: 25
    error: 40