Duplicate Code
debt(d5/e3/b5/t5)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpcpd, phpcs, and rector — all specialist/dedicated tools that must be explicitly added to the workflow. Duplicate code is not caught by the compiler or a default linter out of the box; it requires running a dedicated copy-paste detector like phpcpd.
Closest to 'simple parameterised fix' (e3). The quick_fix states: extract the duplicated block into a shared method, trait, or parent class, using a parameter for slight variations. This is a focused refactor within one component or class hierarchy — more than a single-line swap but not a cross-file architectural change.
Closest to 'persistent productivity tax' (b5). Duplicate code applies across web, cli, and queue-worker contexts and spreads across multiple files over time. Every future bug fix or rule change must be applied in multiple places, slowing down many work streams. It isn't quite load-bearing across the whole architecture (b7), but it consistently taxes maintainers.
Closest to 'notable trap' (t5). The misconception field captures a documented gotcha: developers assume extracting all duplicate code into a shared function always improves design, but two identical snippets in unrelated modules may represent different concepts that will diverge — forcing them together creates hidden coupling. This is a well-known DRY misapplication that many developers eventually learn.
Also Known As
TL;DR
Explanation
When the same logic appears in multiple places, a bug fix or requirement change must be applied everywhere it exists — and inevitably one copy is missed. Duplicate code also makes understanding a codebase harder because readers must verify that two similar-looking blocks are truly identical in behaviour. The fix is to extract the duplicated logic into a named function or method, then call it from all the original sites.
Common Misconception
Why It Matters
Common Mistakes
- Copy-pasting a code block with minor variations instead of extracting a parameterised function.
- Duplicate validation logic in both the model and the controller — they diverge over time.
- Near-duplicate switch statements for related concepts — use a strategy pattern or data-driven lookup.
- Not using array_map/array_filter/array_reduce and writing the same loop logic in multiple places.
Code Examples
// In UserController
$user = User::find($id);
if (!$user) { abort(404); }
// In PostController (exact copy)
$user = User::find($id);
if (!$user) { abort(404); }
// Extracted helper or base controller method
public function findOrFail(int $id): User {
return User::find($id) ?? abort(404);
}
// Or use Eloquent's built-in:
$user = User::findOrFail($id);