Недавно мне попался отличный инструмент для анализа PHP кода. Публикую перевод статьи с обзором этого инструмента.


PhpMetrics использует D3 и несколько сложных алгоритмов для сканирования кода вашего приложения и вывода замысловатых отчетов по результатам.
image


Установка и использование PhpMetrics


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

Окружение

Для опытов нам понадобится изолированное окружение. Как обычно, мы будем использовать наш верный Homestead Improved Vagrant Box, чтобы все читатели имели одинаковую среду для экспериментов.

Установка PhpMetrics

Как и с любым современным PHP проектом, установка очень проста. Установку выполним глобально, сделав его доступным всем проектам на машине.

sudo composer global require 'halleck45/phpmetrics'


Получение кода

Мы протестируем PhpMetrics на двух тяжеловесных проектах: Laravel и Symfony, рассмотрим именно фреймворки, не проекты. Это значит, что мы не будем использовать команду Composer`а create-project, а исследуем исходники каждого фреймворка.

git clone https://github.com/symfony/symfony symframe
git clone https://github.com/laravel/framework lframe

Мы делаем так, чтобы держаться подальше от кода, не относящегося к фреймворку.

Использование PhpMetrics на тяжеловесном проекте

Теперь, когда мы загрузили проекты, давайте запустим на них PhpMetrics.

mkdir Laravel
mkdir Laravel/public
phpmetrics --report-html=/Laravel/public/report_symfony.html symframe
phpmetrics --report-html=/Laravel/public/report_laravel.html lframe

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

homestead.app:8000/report_symfony.html
homestead.app:8000/report_laravel.html

Вот, что мы видим в отчете по Laravel:
image

и вот, что мы получаем для анализа Symfony:
image

Анализ


PhpMetrics предлагает множество метрик. Давайте проясним суть этих кругов и графиков и выясним, на что именно мы смотрим!

Цветовое кодирование

Ознакомившись с руководством к отчету, мы можем сразу отметить, что для Symfony больше оранжево-красного, в то время как для Laravel больше зеленого. Отметим важный момент — насколько больше файлов у Symfony по отношению к Laravel — вы это можете четко видеть, сравнив плотность кругов.
PhpMetrics принимает во внимание людей, имеющих проблемы со зрением. Чекбокс “color blind” меняет цвет кругов с зеленого, желтого и оранжевого на полосы под разными углами.
image

Цикломатическая сложность и показатель поддерживаемости

Если посмотреть внимательно, то становится понятно, что круги представляют собой показатели CC и MI, и, как сказано в документации, большие красные круги, вероятно, будет очень сложно поддерживать.
Оба термина легко гуглятся, но позвольте мне избавить вас от этого и объяснить на пальцах.
Цикломатическая сложность по сути показывает количество всевозможных путей, по которым можно пройти логику скрипта. Чем больше путей, тем выше сложность файла. Хороший способ избежать высокой CC — делать код максимально модульным и атомарным, это происходит естественно при соблюдении SOLID-принципов.
Как говорит Википедия, индекс поддерживаемости вычисляется по определенным формулам на основании следующих метрик — количество строк кода, Мак-Кейба, Холстеда. Количество строк кода — самоочевидно — в буквальном смысле подсчет количества строк кода. Метрика Мак Кейба — на самом деле это второе название цикломатической сложности. Сложность Холстеда — набор формул, которые пытаются заглянуть в синтаксис кода и вывести такие свойства как трудоемкость кодирования, набор уникальных команд программы, сложность понимания программы и т.д. Если вам интересны конкретные формулы, загляните в Википедию.
Принимая все это во внимание, кругам задается размер и цвет, отражая сумму всех стандартных метрик сложности и поддерживаемости кода.

Таблицы

Если вы желаете увидеть все данные в табличной форме, можете выбрать пункт “Explore” в меню отчета.
image

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

Настраиваемые графики

Средняя область в отчете содержит настраиваемый график.
image

В примере выше мы сравниваем для каждого файла соотношение CC (упоминалось выше) и Lcom (насколько методы не связаны друг с другом через свойства), но вы можете легко переключить значения осей X и Y на что-либо другое. Например, тут сопоставление сложности с количеством строк кода — вы можете отметить, что тренд для Laravel более пропорционален — чем больше Loc, тем больше сложность. в то время, как для Symfony картина более размыта для некоторых файлов.
image
Например, файл BinaryMode.php Symfony имеет очень большую сложность при 150 строках кода, а Response.php при 1275 строках имеет очень низкий показатель сложности. Исследуйте файлы, которые дают любопытные результаты и посмотрите, что можно получить из этих наблюдений.

Абстрактность/неустойчивость

Этот график очень хорошо объяснен тут, но если коротко, то средняя диагональная линия называется балансом или главной последовательностью. Цель состоит в том, чтобы ваши классы были как можно ближе к линии, потому что это означает, что они сбалансированы — достаточно абстрактны и достаточно конкретны.
Прим. переводчика: автору по какой-то причине не удалось построить этот график. Чтобы было понятно о чем речь, привожу пример для Yii2.
image

Оценка

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

Карта связей

Карта связей более полезна для маленьких проектов — позволяет увидеть связи между классами. Если класс расширяет или реализует другой, то карта связей покажет это. Из-за того, что в обоих проектах количество классов и связей между ними слишком велико, карта для нашего случая не так полезна — фактически, она у меня не построилась для Symfony. Но если вы попробуете построить ее на тестовом проекте с меньшим числом связей, вы обязательно увидите преимущества.
Прим. переводчика, чтобы было понятно, о чем речь, привожу пример для Yii2
image

Перераспределение

И, наконец, страничка с информацией о перераспределении подытоживает все результаты в более простом виде, чем на вкладке Explore.

Symfony:
image

Laravel:
image

Результаты сравнения


Итак, какие выводы можно сделать из полученных результатов? Не делая глубокого анализа, можно заключить, что:
  1. Laravel более дружественен для новых разработчиков, имеет более простые алгоритмы и менее раздутые файлы.
  2. Laravel кардинально более легковесный. В Symfony как минимум в три раза больше всего — методов, классов, строк кода… он в три раза массивнее.
  3. У Symfony выше относительная сложность (средняя колонка в отчете о перераспределении).
  4. Laravel более стабилен в плане сложности в файлах — сложность пропорциональна строкам кода, в Symfony это не так.
  5. Symfony может поработать над тем, чтобы разделить некоторые сложные файлы на более атомарные — большие красные круги повсюду на первом графике.

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

Заключение


PhpMetrics — очередной инструмент в длинной линейке анализаторов качества кода, но с плюшками. В сравнении с поиском типичных проблем кода стандартными средствами, тут мы видим целый набор новых атрибутов и объяснений в прекрасной форме. Чтобы выяснить, что означает каждый атрибут, обратитесь к таблице.
Будете ли вы использовать PhpMetrics для анализа своего проекта? Встроите ли вы этот инструмент в свою IDE? Видите ли вы этот инструмент постоянным дополнением к вашему процессу непрерывной интеграции?

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


  1. KIBIs
    05.04.2015 14:08
    +1

    Занимательные графики, но вопрос об использовании остается открытым. Как относиться к результатам?


    1. mnv Автор
      05.04.2015 14:17

      На мой взгляд такие инструменты полезны для того, чтобы найти проблемные места в коде, но не принимать рекомендации буквально. Хорошо следить за метриками из CI, например, из Jenkins, где видна динамика собираемых показателей от коммита к коммиту.


    1. allex
      05.04.2015 14:37
      +1

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


    1. KAndy
      05.04.2015 21:41

      Советую CRAP метрику. Особенно для легаси проекта.


  1. nazarpc
    05.04.2015 14:27

    А ещё есть удобный плагин для PhpStorm


  1. voidMan
    05.04.2015 16:40

    Не уверен что это полезно в практическом смысле, но для некоторой общей наглядности полезно. Прикрутил к дженкинсу, коллеги-программисты не очень обрадовались увидев массу огромных красных пятен )


  1. Crankoman
    06.04.2015 07:30
    -1

    Посмотрел на график «Evalution» сразу вспомнил таблицы Рабкина на цветовосприятие. Интересно, кто то при разработке учитывают, что у части людей может быть «цветовая слепота»?


    1. hudson
      06.04.2015 08:33
      +2

      Обратите внимание в правом верхнем углу «I'm colorblind»


    1. Starche
      06.04.2015 10:41

      PhpMetrics принимает во внимание людей, имеющих проблемы со зрением. Чекбокс “color blind” меняет цвет кругов с зеленого, желтого и оранжевого на полосы под разными углами


  1. reimax
    06.04.2015 13:03
    -1

    Заголовок спойлера
    composer global require 'halleck45/phpmetrics'
    
    root@ubuntu:/home/rei/www/project/test# composer global require 'halleck45/phpmetrics'
    Warning: This development build of composer is over 30 days old. It is recommended to update it by running "/usr/local/bin/composer self-update" to get the latest version.
    Changed current directory to /root/.composer
    Warning: This development build of composer is over 30 days old. It is recommended to update it by running "/usr/local/bin/composer self-update" to get the latest version.
    Using version ~1.1 for halleck45/phpmetrics
    ./composer.json has been created
    Loading composer repositories with package information
    Updating dependencies (including require-dev)
      - Installing symfony/yaml (v2.6.6)
        Downloading: 100%         
    
      - Installing symfony/filesystem (v2.6.6)
        Downloading: 100%         
    
      - Installing symfony/config (v2.6.6)
        Downloading: 100%         
    
      - Installing hoa/core (2.15.02.18)
        Downloading: 100%         
    
      - Installing hoa/visitor (1.15.02.26)
        Downloading: 100%         
    
      - Installing hoa/iterator (1.15.02.20)
        Downloading: 100%         
    
      - Installing hoa/stream (0.15.02.25)
        Downloading: 100%         
    
      - Installing hoa/file (0.15.02.19)
        Downloading: 100%         
    
      - Installing hoa/string (2.15.03.25)
        Downloading: 100%         
    
      - Installing hoa/compiler (2.15.02.17)
        Downloading: 100%         
    
      - Installing hoa/regex (0.15.02.24)
        Downloading: 100%         
    
      - Installing hoa/math (0.15.02.23)
        Downloading: 100%         
    
      - Installing hoa/ruler (1.15.02.05)
        Downloading: 100%         
    
      - Installing symfony/console (v2.6.6)
        Downloading: 100%         
    
      - Installing twig/twig (v1.18.0)
        Downloading: 100%         
    
      - Installing halleck45/phpmetrics (v1.1.1)
        Downloading: 100%         
    
    hoa/core suggests installing hoa/console (To use the `hoa` script.)
    hoa/core suggests installing hoa/dispatcher (To use the `hoa` script.)
    hoa/core suggests installing hoa/router (To use the `hoa` script.)
    symfony/console suggests installing symfony/event-dispatcher ()
    symfony/console suggests installing symfony/process ()
    symfony/console suggests installing psr/log (For using the console logger)
    Writing lock file
    Generating autoload files
    
    root@ubuntu:/home/rei/www/project/test# phpmetrics --report-html=myreport.html /home/rei/www/project/test/
    phpmetrics: команда не найдена
    


    1. mnv Автор
      06.04.2015 13:26

      Система не находит phpmetrics, пропишите каталог с phpmetrics в PATH, т.е. надо сделать что-то вроде этого:

      export PATH=~/.composer/vendor/bin:$PATH
      

      Или вызывайте phpmetrics, указывая полный путь к phpmetrics.


      1. reimax
        06.04.2015 13:28

        Нашел на гите инструкцию, с ней запустилось. Спасибо, инструмент очень интересный.


    1. isden
      06.04.2015 14:39

      А можно просто скачать .phar с оффсайта и запускать его.


  1. vstaf
    06.04.2015 16:57

    Тоже, в свое время, разработчики попросили добавить выполнение phpmetrics.
    В итоге даже добавил кнопку для просмотра отчета в каждой dev-задаче Jenkins
    image


  1. Argnist88
    15.04.2015 07:52

    На проекте из 990 файлов падает с ошибкой PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 33554432 bytes).


    1. FractalizeR
      15.04.2015 10:57

      Создайте лучше issue на github. Так хоть разработчик увидит.


      1. isden
        15.04.2015 13:10
        +1

        А может быть просто memory_limit чуть увеличить? У меня с 256M сабж нормально прожевал проект с почти 4 тыщами файлов.


        1. FractalizeR
          15.04.2015 13:23
          +1

          Может. Но автора нужно уведомить все равно. Может быть, там утечка памяти или ее перерасход.