← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Enums — First-Class Enumerations (PHP 8.1)

PHP PHP 8.1+ Intermediate
debt(d5/e3/b3/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan and rector, with automated flagged as no and a code_pattern for class constants used as enum replacements. PHPStan can detect type-unsafe patterns and incorrect comparisons, but it requires configuration and is not a default linter — it's a specialist static analysis tool.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix states: replace class constant patterns with backed enums, use tryFrom() for user input, use in match expressions. This is a localised refactor pattern — replacing constants with enum cases is mechanical and confined to one component at a time, not a one-liner but not cross-cutting either.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Applies to web, cli, and queue-worker contexts, so the scope is broad in principle, but the burden is per-use-site: each class that uses string constants instead of enums pays its own tax independently. The choice doesn't impose strong gravity on unrelated parts of the codebase.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception field explicitly states that developers familiar with Java/TypeScript expect enums to be typed numbers, but PHP enums are singleton objects with methods and interfaces. Additionally, the common mistakes highlight == vs === comparison and from() vs tryFrom() gotchas — these are documented but non-obvious surprises a competent developer would likely hit.

About DEBT scoring →

TL;DR

PHP 8.1 native enums replace class constant hacks — providing type-safe, enumerable, matchable values with optional backing values (: string or : int).

Explanation

Two enum types: pure (unit) enums: enum Status { case Active; case Inactive; } and backed enums: enum Status: string { case Active = 'active'; case Inactive = 'inactive'; }. Methods, interfaces, and constants in enums. Static methods. from() / tryFrom() for backed enums. cases() returns all cases. Enums extend UnitEnum (pure) or BackedEnum (backed). Cannot be instantiated with new. Cannot extend classes. Enum cases are singletons — Status::Active === Status::Active always. In match expressions: exhaustive matching. In type hints: function process(Status $status). Compare with class constants: no type safety, no first-class status.

Common Misconception

PHP enums are like Java/TypeScript enums which are just typed numbers — PHP enums are objects (singletons), can have methods, implement interfaces, and backed enums have actual string/int values.

Why It Matters

Enums eliminate the class-constant-as-enum pattern, providing type safety (Status not string), exhaustive matching in match expressions, and self-documenting code.

Common Mistakes

  • Comparing enum cases with == instead of === — always use ===.
  • Using string class constants as enum replacement — loses type safety.
  • Not using tryFrom() for user input — from() throws on invalid value.

Code Examples

✗ Vulnerable
// Class constants — no type safety:
class Status {
    const ACTIVE = 'active';
    const INACTIVE = 'inactive';
}
function setStatus(string $status) {} // Accepts any string
✓ Fixed
enum Status: string {
    case Active = 'active';
    case Inactive = 'inactive';
}

function setStatus(Status $status): void {}
setStatus(Status::Active); // Type-safe

// User input:
$status = Status::tryFrom($request->input('status')) ?? Status::Active;

Added 23 Mar 2026
Views 52
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 1 ping W 0 pings T 1 ping F 1 ping S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 2 pings F 0 pings S 0 pings S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 7 Google 6 Unknown AI 5 ChatGPT 4 Perplexity 4 SEMrush 4 Ahrefs 3 Scrapy 2 Claude 1 Meta AI 1 Sogou 1 PetalBot 1
crawler 35 crawler_json 2 pre-tracking 2
DEV INTEL Tools & Severity
🔵 Info ⚙ Fix effort: Medium
⚡ Quick Fix
Replace class constant patterns with backed enums. Use Status::tryFrom() for user input. Use in match expressions for exhaustive handling.
📦 Applies To
PHP 8.1+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
class.*const [A-Z]
Auto-detectable: ✗ No phpstan rector
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: Class Tests: Update


✓ schema.org compliant