Выявление повторяющегося кода в проекте PHP

У меня есть один файл PHP в устаревшем проекте, длина которого не менее нескольких тысяч строк. Он преимущественно разделяется на несколько различных условных блоков с помощью оператора switch примерно с 10 вариантами. В каждом случае есть что-то вроде очень похожего - если не точного дубликата - блока кода. Какие методы доступны для меня, чтобы идентифицировать эти блоки кода как одинаковые или близкие к одинаковым, чтобы я мог абстрагироваться от этого кода и начать рефакторинг всего файла? Я знаю, что это возможно очень вручную (разделите каждый оператор case в коде на отдельные файлы и Diff), но мне интересно, какие инструменты я мог бы использовать для ускорения этого процесса.

Спасибо.


person robjmills    schedule 23.09.2010    source источник


Ответы (4)


Вы можете использовать phpcpd.

phpcpd - это детектор копирования / вставки (CPD) для кода PHP. Он сканирует проект PHP на предмет дублирования кода.

Дополнительные ресурсы:

person Gordon    schedule 23.09.2010
comment
это выглядит как отличная отправная точка и действительно удобный инструмент. Благодарность - person robjmills; 23.09.2010
comment
К сожалению, это обнаруживает только повторяющиеся операторы PHP - у меня есть проект с тысячами строк дублированного HTML в шаблонах PHP, и этот инструмент фактически обнаруживает лишь довольно небольшое количество этих строк. - person mindplay.dk; 15.05.2019

Вы можете использовать phpunit PMD (Project Mess Detector) для обнаружения повторяющихся блоков кода.

Он также может вычислить цикломатическую сложность вашего кода.

Вот скриншот вкладки pmd в phpuc: pmd tab

person greg0ire    schedule 23.09.2010
comment
Цикломатическая сложность не имеет ничего общего с кодом копирования и вставки. И глядя на документы для PMD, я бы сказал, что он не может обнаружить такой повторяющийся код. Тем не менее, это, без сомнения, хороший инструмент. - person Gordon; 23.09.2010
comment
Обновил свой пост, думаю теперь понятнее. Я также думаю, что phpunit-pmd использует phpcpd, не так ли? Или это другая реализация? - person greg0ire; 23.09.2010
comment
Меня, возможно, смутила метка вкладки в этом (отличном) пользовательском интерфейсе, которая может вызывать несколько инструментов. - person greg0ire; 23.09.2010
comment
это определенно имеет значение. но проверьте hudson и арбитраж для альтернатив. - person Gordon; 23.09.2010
comment
Спасибо за эти уточнения. Добавление этого поста в избранное :-) - person greg0ire; 23.09.2010

См. Наш инструмент PHP Clone Detector.

Это обнаруживает как точные копии, так и возможные ошибки, несмотря на переформатирование, вставку / удаление комментариев, замену имен переменных, добавление / замену субблоков и т. Д.

PHPCPD, насколько я могу судить, находит только (токен) последовательности, которые точно такие же. При этом упускается много клонов, поскольку наиболее распространенной операцией после копирования и вставки является редактирование для настройки. Таким образом, он упустил бы те самые клоны, которые OP пытается найти.

person Ira Baxter    schedule 24.10.2010
comment
Прекратите распространять FUD. phpcpd сравнивает без учета пробелов. - person cweiske; 30.04.2011
comment
@cweiske: Это означает, что он находит только идентичные последовательности токенов, о чем я сказал. Он не найдет параметризованных клонов, то есть тех, где код был отредактирован копированием и вставкой. Он может найти части таких клонов, но это гораздо менее полезно. - person Ira Baxter; 30.04.2011
comment
@cweiske: Вы изучили отчет Joomla, представленный на сайте? Он показывает параметризованные клоны, о которых я говорю. Запустите на нем PHPCPD и сравните результаты. Я думаю, ты удивишься. - person Ira Baxter; 30.04.2011
comment
@cweiske: FWIW, сайт github для PHPCPD github.com/sebastianbergmann/phpcpd показывает пример запуска на 60 000 строк кода, где он находит только 0,2% клонов (точное совпадение). Это, откровенно говоря, жалкое количество клонов, исходя из моего десятилетия создания / запуска детекторов клонов для многих языков; большая часть кода любого масштаба имеет 5-20% и более. Разница связана с обнаружением параметризованных клонов. Вы можете загрузить CloneDR и попробовать сами. - person Ira Baxter; 30.04.2011

Вы могли бы поместить блоки в отдельные файлы и просто запустить на них diff?

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

person mikera    schedule 23.09.2010
comment
вот что я имел в виду под ручным методом. хотя спасибо за вклад - person robjmills; 23.09.2010