Nested Ternary
ID |
php.nested_ternary |
Severity |
low |
Remediation Complexity |
medium |
Remediation Risk |
low |
Remediation Effort |
medium |
Resource |
Code Smell |
Language |
Php |
Tags |
readability, simplification |
Description
Reports a ternary conditional expression (cond ? a : b, or the short form a ?: b) that
contains another ternary in its condition or in either of its branches. The maximum allowed
nesting depth is configurable through the maxTernaryDepth property (default 1, meaning any
ternary placed inside another is flagged).
Rationale
A single ternary is a compact, readable replacement for a small if/else. Once ternaries
are stacked inside one another the expression becomes a puzzle: the reader has to track
operator precedence and right-associativity to work out which branch belongs to which
condition, and a misplaced parenthesis silently changes the result. The null-coalescing
operator ?? is deliberately not treated as a ternary, so idiomatic fallback chains such as
$a ?? $b ?? $default are left alone.
<?php
// FLAW — a ternary nested in the arm of another ternary
$label = $x > 0 ? ($x > 10 ? 'big' : 'small') : 'neg';
// OK — a single, flat ternary
$label = $x > 0 ? 'pos' : 'neg';
// OK — null-coalescing chain, not a ternary
$name = $first ?? $second ?? 'anonymous';
Remediation
Unfold the nested ternary into an if/elseif/else chain, or replace it with a match
expression when each branch maps a value to a result. Both forms make every condition and its
outcome explicit and remove the precedence guesswork.