Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Phpcpd Laravel Package

systemsdk/phpcpd

A maintained fork of phpcpd, the Copy/Paste Detector for PHP. It scans your codebase for duplicated code using tokenization, reports clones with file and line info, and supports configurable thresholds and CI integration to help keep projects clean.

Deep Wiki
Context7

Technical Evaluation

What the package is: systemsdk/phpcpd is a maintained fork of the abandoned sebastian/phpcpd Copy/Paste Detector. It is a CLI-only, token-based duplication scanner for PHP that emits human-readable output and PMD-CPD XML, and returns a non-zero exit code when duplicate blocks exceed configured thresholds (--min-lines, --min-tokens, --fuzzy). It has no runtime role in a Laravel application.

Architecture fit: Excellent from a coupling standpoint. It installs as a require-dev Composer dependency, exposes a single binary (vendor/bin/phpcpd), and requires no service provider, config publish, facade, or application bootstrap. There is zero production surface area — the blast radius of adoption is limited to developer machines and CI runners. This is the lowest-risk category of dependency a Laravel team can take on.

Integration feasibility: High. composer require --dev systemsdk/phpcpd followed by vendor/bin/phpcpd app/ produces a usable baseline in minutes. The --log-pmd output is a stable, widely-consumed schema that SonarQube, Jenkins, and GitLab can ingest. Exit-code gating maps cleanly onto any CI system, and it composes with existing Composer scripts, Makefiles, or Laravel Pint/PHPStan jobs without conflict.

Technical risk: The risk is not architectural — it is lifecycle and supply chain. Signals are weak: 15 stars, a single-maintainer fork lineage, and a repository field reported as unknown, which prevents provenance verification. The upstream project was archived, so this fork inherits an aging tokenizer and detection engine. The real technical concern is PHP language drift: new syntax (readonly classes, enums, property hooks, asymmetric visibility) can cause parse failures or, worse, silent mis-tokenization that produces both false positives and false negatives. A recent release date is reassuring but must be corroborated against actual commit activity and a declared PHP version matrix.

Key questions for the maintainer/team:

  • Which PHP versions are explicitly supported and tested in CI (7.4? 8.1–8.4?), and is PHP 8.4 syntax covered?
  • Does the fork track upstream bug/security fixes, or has it diverged permanently? Is there a changelog?
  • Is a PHAR distribution published, and is it signature-verified for CI use?
  • What are the transitive sebastian/* dependencies, and do they conflict with PHPUnit or other dev tooling already pinned in the project?
  • Does it support directory exclusion, filename patterns, and per-directory threshold overrides?
  • What is the observed runtime and peak memory on a repo of our size (~Nk LOC)?
  • Who is the maintainer, and what is the bus factor / issue triage latency?

Verdict: Conditional adopt for a pilot. Architecturally safe, operationally cheap, but lifecycle risk is real — treat it as a replaceable utility, not a load-bearing quality gate.

Integration Approach

Stack fit: Composer-native and framework-agnostic. Because it never loads inside the Laravel application, Laravel version compatibility is a non-issue; the only version constraint that matters is the PHP runtime on developer machines and CI images. It sits alongside Pint (style), PHPStan/Larastan (types), and PHPUnit (behavior) as a fourth, orthogonal quality dimension.

Migration path: If the team previously used sebastian/phpcpd, this is a near drop-in: same binary name, same CLI flags, same PMD-CPD XML schema. Migration is a one-line composer.json change plus a lockfile update, and any downstream PMD XML parser (SonarQube, Jenkins CPD plugin, custom dashboards) continues to work unchanged. If the team has no existing duplication tooling, migration cost is effectively zero — there is nothing to unwind.

Compatibility checks before merging: Confirm the package's PHP constraint against the CI image; run composer why-not / check for conflicts with PHPUnit's pinned sebastian/* versions; verify the binary runs on both the local dev PHP (likely 8.3/8.4 via Herd/Sail) and the CI PHP. Watch for the case where the fork's sebastian/finder-facade or tokenizer dependencies force a downgrade of an otherwise-current dev dependency tree.

Sequencing:

  1. Add as require-dev, pinned to an exact version, on a branch.
  2. Run a baseline scan over app/ and tests/ only; record duplication percentage and the top offenders. Do not gate anything yet.
  3. Tune --exclude for vendor/, storage/, bootstrap/cache/, database/migrations/, and generated code; adjust --min-lines/--min-tokens to suppress noise from DTOs, config arrays, and Eloquent relationship boilerplate.
  4. Land a non-blocking CI job that publishes the PMD XML as an artifact and surfaces the trend.
  5. Ratchet: once the baseline is stable and trusted, convert to a blocking gate pinned just above current duplication, and tighten over subsequent sprints rather than all at once.

Operational Impact

Maintenance: Low effort, moderate attention. Pin the exact version in composer.json and let Renovate/Dependabot propose bumps for human review rather than auto-merging, given the small maintainer base. Budget a recurring check (quarterly) on whether the fork is still alive; keep a documented fallback (jscpd with a PHP grammar, or Java-based PMD CPD in a sidecar container) so a stalled fork is an afternoon's substitution, not a project.

Support: Community-only. No commercial backing, no vendor SLA, no visible CVE intake process. Internal ownership should sit with whichever engineer owns static analysis; document the tool, the thresholds chosen and why, and the exclusion list so it does not become tribal knowledge.

Scaling: Duplication detection is comparative across token windows, so runtime grows faster than linearly with codebase size. On a large Laravel monolith this can move from seconds to several minutes. Mitigations: scope the scan to app/ and tests/ rather than the repo root, exclude generated and vendored trees aggressively, and in monorepos split into per-package jobs so a slow module does not serialize the whole pipeline. There is no meaningful incremental/caching mode, so plan for full scans in CI rather than diff-only runs.

Failure modes to design around:

  • Memory exhaustion on large token sets — set an explicit CI memory limit and know the ceiling before it bites.
  • Job timeout as the codebase grows — alert on job-duration trend, not just pass/fail.
  • Fatal parse errors on unsupported new PHP syntax, which abort the whole scan rather than skipping the file — a single offending file can turn the gate red for the wrong reason.
  • Silent under-detection from stale tokenization, which reads as "clean" and is the most dangerous outcome.
  • Exit-code conflation — 1 for "duplicates found" versus a distinct failure for scan errors; CI wrappers must distinguish these or a broken tool will be mistaken for a clean repo.
  • False positives on migrations, seeders, DTOs, and config arrays, which erode trust and lead teams to disable the gate entirely.

Ramp-up: Very low. Most developers need no training — the output is self-explanatory and the tool is not a pre-commit blocker by default. Realistic effort is roughly half a day for one engineer to wire the CI job, tune thresholds against the baseline, and write a short README section. Organization-wide comprehension cost is negligible.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
takashato/laravel-vietqr
aitor24/laralang
kraenzle-ritter/entity-relations
dindigital/din-image
pomirleanu/image-colors
sawmainek/laravel-api-generator
delatbabel/jsonresponses
mouhamedfd/permissions-generator
eduplus/qr
laravel2580/idehelpers
delatbabel/viewpages
anavel/gettext
muhamadrezaar/highcharts
delatbabel/keylists
frankkessler/salesforce-laravel-oauth2-rest
anavel/foundation
wdmtech/enviricons
eii/laravel-captcha
muka/shape-reader
tdt/json