Подтвердить что ты не робот

Идентификация повторяющегося кода в PHP-проекте

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

Спасибо.

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

Ответ 4

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

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