phpcpd-next: شکار کدهای کپیپیستشده در PHP
خلاصهٔ کاملتر
تو مقالهای که پاول ردموند تو Laravel News نوشته، ابزار جدیدی به اسم phpcpd-next معرفی میشه که کد PHP رو میگرده دنبال بلوکهایی که از یه جا به جای دیگه کپی شدن؛ همون تکرارهایی که تو ریویو راحت از چشم میافتن و بعداً همگام نگهداشتنشون دردسر میشه. این ابزار رو لوچانو فدریکو پریرا نگه میداره و جانشین phpcpd سباستین برگمان (که آرشیو شده) حساب میشه و بهصورت drop-in با همون دستور phpcpd کار میکنه.
نکتهی اصلیش اینه که فقط کپی کلمهبهکلمه رو پیدا نمیکنه. سه موتور تشخیص داره: Rabin-Karp برای تطبیق دقیق، TokenBag برای وقتی خطها جابهجا شدن، و یه موتور suffix tree اختیاری برای کلونهای gapped؛ جایی که یه دستور بین دو بلوکِ تقریباً یکسان اضافه یا حذف شده. یه حالت --fuzzy هم هست که به تغییر اسم متغیرها حساس نیست. تو اجرای پیشفرض، دو موتور Rabin-Karp و TokenBag با هم اجرا میشن.
# Default: exact + reordered detection
phpcpd src/
# Gapped Type-3 clones via suffix tree
phpcpd --algorithm=suffixtree src/خروجی کنسول بهجای اینکه فقط شماره خط بده، محدودهی تکرارشده رو نشون میده و پیشنهاد ریفکتور هم میده. کلاً چهار فرمت خروجی داره: متن کنسول، PMD-CPD XML، JSON و SARIF 2.1.0. با SARIF کلونها مستقیم تو تب Security گیتهاب ظاهر میشن؛ کلونهای ناسازگار (واگرا) بهعنوان warning و کلونهای دقیق بهعنوان note علامت میخورن.
به گفتهی نویسنده، غیر از خط فرمان، میشه تشخیص رو داخل خودِ برنامه هم اجرا کرد؛ با یه فراخوانی استاتیک detect()، بدون اینکه بخوای پروسهی جدا بزنی یا فایل گزارش بسازی:
use LucianoPereira\PhpcpdNext\Phpcpd;
$clones = Phpcpd::detect(
paths: 'app',
minTokens: 60,
algorithm: null, // null = Rabin-Karp + TokenBag
preset: 'laravel',
);یه trait به اسم AssertNoDuplication هم همراهشه که تکرار کد رو تبدیل به یه assertion تو تست میکنه، پس duplication میشه یه چکِ رگرسیون. برای CI هم امکاناتی مثل exit codeی معنادار، کش کامل نتایج و ایندکس افزایشیِ per-file داره. خودِ ابزار PHP 8.5 به بالا میخواد، هیچ وابستگی runtime تو Composer نداره و نتایجش قطعیه. پریستهای فریمورک هم داره که Laravel یکیشونه.
نکات کلیدی:
- سه موتور تشخیص: Rabin-Karp (دقیق)، TokenBag (جابهجاشده) و suffix tree اختیاری (gapped)
- چهار فرمت خروجی، از جمله SARIF 2.1.0 برای Code Scanning گیتهاب
- API داخلی با detect() و یه trait برای assertion تو PHPUnit
- امکانات CI: exit codeی معنادار، کش نتایج و ایندکس افزایشی
- نیازمند PHP 8.5+، بدون وابستگی runtime تو Composer




