acc-check-nesting-depth
Nesting Depth Check
Analyze PHP code for excessive nesting depth and complexity.
Detection Thresholds
| Depth | Classification |
|---|---|
| 1-2 | ✅ Ideal |
| 3 | ⚠️ Acceptable |
| 4 | 🟡 Deep - refactor recommended |
| 5+ | 🟠 Too deep - must refactor |
Detection Patterns
1. Deep Nesting
// DEPTH 5: Arrow code / pyramid of doom
public function process(Request $request): Response
{
if ($request->isValid()) { // 1
if ($user = $request->getUser()) { // 2
if ($user->hasPermission('edit')) { // 3
foreach ($request->getItems() as $item) { // 4
if ($item->isActive()) { // 5
$this->handle($item);
}
}
}
}
}
}
// DEPTH 2: Using early returns
public function process(Request $request): Response
{
if (!$request->isValid()) {
return $this->badRequest();
}
$user = $request->getUser();
if (!$user) {
return $this->unauthorized();
}
if (!$user->hasPermission('edit')) {
return $this->forbidden();
}
$activeItems = array_filter(
$request->getItems(),
fn($item) => $item->isActive()
);
foreach ($activeItems as $item) {
$this->handle($item);
}
}
2. Complex Conditionals
// COMPLEX: Multiple nested conditions
if ($order->isPaid()) {
if ($order->isShipped()) {
if ($order->isDelivered()) {
if (!$order->isReturned()) {
$this->complete($order);
}
}
}
}
// SIMPLIFIED: Combined condition
if ($order->canBeCompleted()) {
$this->complete($order);
}
// Or with early return
if (!$order->isPaid()) return;
if (!$order->isShipped()) return;
if (!$order->isDelivered()) return;
if ($order->isReturned()) return;
$this->complete($order);
3. Nested Loops
// DEEP: Triple nested loop
foreach ($categories as $category) {
foreach ($category->getProducts() as $product) {
foreach ($product->getVariants() as $variant) {
foreach ($variant->getOptions() as $option) {
$this->process($option);
}
}
}
}
// BETTER: Extract methods
foreach ($categories as $category) {
$this->processCategory($category);
}
private function processCategory(Category $category): void
{
foreach ($category->getProducts() as $product) {
$this->processProduct($product);
}
}
private function processProduct(Product $product): void
{
foreach ($product->getVariants() as $variant) {
$this->processVariant($variant);
}
}
4. Callback Nesting (Callback Hell)
// DEEP: Nested callbacks
$this->service->fetch($id, function($result) {
$this->processor->process($result, function($processed) {
$this->sender->send($processed, function($sent) {
$this->logger->log($sent, function($logged) {
$this->cleanup($logged);
});
});
});
});
// FLAT: Sequential or promise-based
$result = $this->service->fetch($id);
$processed = $this->processor->process($result);
$sent = $this->sender->send($processed);
$this->logger->log($sent);
$this->cleanup($sent);
5. Switch in If in Loop
// DEEP: Mixed control structures
foreach ($items as $item) {
if ($item->isActive()) {
switch ($item->getType()) {
case 'A':
if ($item->hasFeature()) {
$this->handleTypeA($item);
}
break;
case 'B':
if ($item->isValid()) {
$this->handleTypeB($item);
}
break;
}
}
}
// BETTER: Strategy pattern + filter
$activeItems = array_filter($items, fn($i) => $i->isActive());
foreach ($activeItems as $item) {
$handler = $this->handlerFactory->create($item->getType());
$handler->handle($item);
}
Refactoring Techniques
Early Return / Guard Clauses
// Before
function process($data) {
if ($data !== null) {
if ($data->isValid()) {
if ($data->canProcess()) {
// actual logic
}
}
}
}
// After
function process($data) {
if ($data === null) return;
if (!$data->isValid()) return;
if (!$data->canProcess()) return;
// actual logic (no nesting)
}
Extract Method
// Before
foreach ($orders as $order) {
if ($order->isPaid()) {
foreach ($order->getItems() as $item) {
if ($item->needsShipping()) {
$this->ship($item);
}
}
}
}
// After
foreach ($orders as $order) {
$this->processOrder($order);
}
private function processOrder(Order $order): void
{
if (!$order->isPaid()) return;
$this->shipItems($order->getItems());
}
private function shipItems(array $items): void
{
foreach ($items as $item) {
if ($item->needsShipping()) {
$this->ship($item);
}
}
}
Replace Conditional with Polymorphism
// Before: Deep switch
switch ($type) {
case 'email':
if ($config['html']) {
// ...
} else {
// ...
}
break;
case 'sms':
// ...
}
// After: Strategy pattern
interface NotificationChannel {
public function send(Notification $notification): void;
}
class EmailChannel implements NotificationChannel { }
class SmsChannel implements NotificationChannel { }
Decompose Conditional
// Before
if ($date->before($SUMMER_START) || $date->after($SUMMER_END)) {
$charge = $quantity * $winterRate + $winterServiceCharge;
} else {
$charge = $quantity * $summerRate;
}
// After
if ($this->isWinter($date)) {
$charge = $this->winterCharge($quantity);
} else {
$charge = $this->summerCharge($quantity);
}
Grep Patterns
# Find nested if statements
Grep: "if\s*\([^)]+\)\s*\{[^}]*if\s*\(" --glob "**/*.php"
# Find nested foreach
Grep: "foreach.*foreach" --glob "**/*.php"
# Count indentation levels (manual analysis)
Severity Classification
| Depth | Severity |
|---|---|
| 4 | 🟡 Minor |
| 5 | 🟠 Major |
| 6+ | 🔴 Critical |
Output Format
### Nesting Depth: [Description]
**Severity:** 🟠/🟡
**Location:** `file.php:line`
**Depth:** 5 levels
**Issue:**
Method `processOrder` has 5 levels of nesting, making it difficult to follow.
**Code Structure:**
if ($request->isValid()) // Level 1 if ($user = getUser()) // Level 2 if ($user->hasPermission()) // Level 3 foreach ($items) // Level 4 if ($item->isActive()) // Level 5
**Suggested Refactoring:**
```php
// Use early returns to flatten
if (!$request->isValid()) return;
if (!$user = getUser()) return;
if (!$user->hasPermission()) return;
$activeItems = $this->filterActiveItems($items);
foreach ($activeItems as $item) {
$this->handle($item);
}
More from dykyi-roman/awesome-claude-code
detect-code-smells
Detects code smells in PHP codebases. Identifies God Class, Feature Envy, Data Clumps, Long Parameter List, Long Method, Primitive Obsession, Message Chains, Inappropriate Intimacy. Generates actionable reports with refactoring recommendations.
15clean-arch-knowledge
Clean Architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Clean Architecture and Hexagonal Architecture audits.
15ddd-knowledge
DDD architecture knowledge base. Provides patterns, antipatterns, and PHP-specific guidelines for Domain-Driven Design audits.
14testing-knowledge
Testing knowledge base for PHP 8.4 projects. Provides testing pyramid, AAA pattern, naming conventions, isolation principles, DDD testing guidelines, and PHPUnit patterns.
12bug-root-cause-finder
Root cause analysis methods for PHP bugs. Provides 5 Whys technique, fault tree analysis, git bisect guidance, and stack trace parsing.
12solid-knowledge
SOLID principles knowledge base for PHP 8.4 projects. Provides quick reference for SRP, OCP, LSP, ISP, DIP with detection patterns, PHP examples, and antipattern identification. Use for architecture audits and code quality reviews.
11