Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама
Новини 04 липня 2026

Детектор дублювання коду phpcpd-next для PHP 8.5+

phpcpd-next сканує PHP-код і виявляє блоки, які були скопійовані з одного місця в інше - той тип дублювання, який легко пропустити під час ревʼю коду, але складно підтримувати синхронізованим згодом.

Інструмент підтримується Luciano Federico Pereira як наступник архівованого phpcpd від Sebastian Bergmann і залишається повністю сумісною заміною з тією ж командою phpcpd.

Що нового: більше ніж точне копіювання

На відміну від попередньої версії, phpcpd-next виявляє не лише дослівні копії, а й дублікати, де рядки були переупорядковані або де між двома ідентичними блоками додали чи видалили один вираз:

  • Три алгоритми детекції - Rabin-Karp (точні збіги), TokenBag (виявлення переупорядкованих фрагментів) та опціональне суфіксне дерево (для клонів Type-3 з пропусками), плюс режим --fuzzy для нечутливості до перейменувань
  • Чотири формати виводу - консольний текст, PMD-CPD XML, JSON та SARIF 2.1.0 для GitHub Code Scanning
  • Headless API для виклику детекції всередині процесу, плюс PHPUnit-трейт, що перетворює перевірку дублювання на тестове твердження
  • Можливості для CI - значущі exit-коди, повне кешування результатів та інкрементальна індексація по файлах
  • Пресети для фреймворків, включно з Laravel, із CLI-прапорцями для перевизначення налаштувань пресетів
  • PHP 8.5+ без runtime-залежностей Composer та детерміністичні результати

Три алгоритми, що працюють разом

Більшість детекторів copy/paste знаходять лише точне дублювання. phpcpd-next за замовчуванням запускає Rabin-Karp (точні послідовні збіги) та TokenBag (overlap незалежно від порядку, тому переставлені вирази також реєструються) одночасно при кожному запуску. Алгоритм суфіксного дерева для клонів з пропусками - коли між ідентичними блоками вставили або видалили вираз - активується опціонально:

# За замовчуванням: точна + детекція переупорядкованих фрагментів
phpcpd src/

# Лише Rabin-Karp (швидше, без детекції переупорядкування)
phpcpd --rk src/

# Клони Type-3 з пропусками через суфіксне дерево
phpcpd --algorithm=suffixtree src/

Консольний вивід вказує на продубльовані діапазони та пропонує рефакторинг замість простого переліку номерів рядків:

Found 2 code clones with 21 duplicated lines in 2 files:
- app/Services/Billing.php:12-33 (21 lines)
  app/Services/Invoicing.php:40-61
→ Consider extracting the shared lines into a reusable method or constant.
37.50% duplicated lines out of 56 total lines of code.

Вивід SARIF для GitHub Code Scanning

Поряд із PMD-CPD XML та JSON, phpcpd-next генерує SARIF 2.1.0, тому клони відображаються у вкладці Security на GitHub. Неузгоджені (розбіжні) клони маркуються рівнем warning, точні клони - note:

- name: Detect duplicated code
  run: vendor/bin/phpcpd --log-sarif=phpcpd.sarif src/ || true

- name: Upload results
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: phpcpd.sarif

Headless API та PHPUnit-твердження

Окрім CLI, детекція виконується всередині процесу через статичний виклик detect() - без запуску shell-команд, без файлів звітів:

use LucianoPereira\PhpcpdNext\Phpcpd;

$clones = Phpcpd::detect(
    paths: 'app',
    minTokens: 60,
    algorithm: null,       // null = Rabin-Karp + TokenBag
    preset: 'laravel',
);

foreach ($clones as $clone) {
    echo $clone->numberOfLines(), " lines\n";
}

Вбудований трейт перетворює це на тест, тому дублювання стає регресійною перевіркою, що падає з локаціями клонів:

use LucianoPereira\PhpcpdNext\PHPUnit\AssertNoDuplication;
use PHPUnit\Framework\TestCase;

final class DuplicationTest extends TestCase
{
    use AssertNoDuplication;

    public function test_app_is_dry(): void
    {
        $this->assertNoDuplication(__DIR__ . '/../app', minTokens: 70);
    }
}

Інкрементальне кешування для CI

Для великих кодових баз --cache зберігає результати, ключовані відбитком конфігурації та хешем маніфесту файлів, відтворюючи кешований результат, коли нічого не змінилося. --incremental йде далі, повторно токенізуючи лише змінені файли та використовуючи решту з індексу по файлах (лише Rabin-Karp), друкуючи підсумок на зразок (incremental index: 412 reused, 3 scanned):

- uses: actions/cache@v4
  with:
    path: .phpcpd-cache
    key: phpcpd-${{ hashFiles('**/*.php') }}
    restore-keys: phpcpd-

- run: vendor/bin/phpcpd --incremental --cache-dir .phpcpd-cache src/

Встановлення та використання

Інструмент вимагає PHP 8.5+, ext-dom та ext-mbstring, і встановлюється як dev-залежність:

composer require --dev phpcpd-next/phpcpd
vendor/bin/phpcpd src/

Пресет Laravel сканує app, routes, database та config, виключаючи vendor-код, Blade-шаблони, міграції та файли IDE-helper:

vendor/bin/phpcpd --preset=laravel app/Services --min-tokens=60

Вихідний код та повну документацію можна знайти на GitHub.

5

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

Filament v5.10.0
Новини 12 жовтня 2026

Filament v5.10.0: сітка в rich editor, скелетони таблиць і десятки виправлень

Вийшов Filament v5.10.0: елементи керування сіткою в rich editor, допоміжний контент для віджетів-графіків, скелетони завантаження таблиць, submitOnCompletion() для OneTimeCodeInput та багато виправлень авторизації, доступності й стану.

22
Laravel AI SDK на практиці
Новини 09 жовтня 2026

Laravel AI SDK на практиці: агент, що стоїть за There There

Фрік Ван дер Гертен розповідає, як у Spatie побудували AI-шар хелпдеска There There на Laravel AI SDK: клас агента, інструменти з типізованою JSON-схемою та делегування роботи звичайним domain-діям.

18

Вакансії за темою

Alcor
7 днів тому

PHP Tech Lead

Технічний лідер платформи для управління контракторами: визначає технічне бачення та архітектуру, будує дорожню карту, відповідає за доставку і стабільність у продуктивному середовищі. Основний стек: PHP, Laravel, DDD, CQRS, Event Sourcing, MySQL, AWS, Terraform. Вимоги: 4+ роки досвіду Tech Lead або архітектора, 8+ років PHP, сильне моделювання даних, тестування (PHPUnit, Playwright). Керівництво командою з 2 розробників і 2 QA без прямого менеджменту.

Real Estate Bees
29 днів тому

Backend Engineer (PHP/Laravel)

Розробник Backend на Laravel 12/PHP 8.2 для revenue-critical систем з REST API, бізнес-логікою, інтеграцією третіх сервісів і Redis-черг. Потрібен досвід 3+ років PHP/Laravel, знання Domain-Driven Design, PostgreSQL, тестування та AI-інструментів. Позиція передбачає архітектурну трансформацію з legacy-коду до domain-first структури, з відповідальністю від вимог до production.

Middle PHP developer

Розробник PHP middle-рівня для високонавантаженої веб-платформи Social Casino/Online Casino, яка активно масштабується. Основний стек: PHP 7.4, Symfony 4, Yii, PostgreSQL 14, Redis, RabbitMQ, NGINX; частина сервісів переходить на мікросервіси на Symfony. Вимоги: 3-4+ роки продуктового досвіду з PHP, Yii або Symfony, PostgreSQL, розуміння REST API, досвід роботи з Git, знання ООП і SOLID. Буде плюсом досвід з брокерами повідомлень і DDD.

Пакети за темою

Kalimera

welldigit/kalimera

Interactive installer that scaffolds Laravel applications the Well Digit way.

v1.0.0 12

Bagisto

bagisto/bagisto

Bagisto — це платформа для електронної комерції, побудована на Laravel. Вона надає готове рішення для створення та управління інтернет-магазинами з підтримкою каталогу товарів, замовлень, платежів та клієнтів.

28,244 v2.5.0 13 26