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

Enum Methods, Interfaces & Constants (PHP 8.1)

php PHP 8.1+ Intermediate
debt(d5/e3/b3/t3)
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 psalm as the tools that catch misuse (e.g. Enum::from() on untrusted input instead of tryFrom()). These are specialist static analysis tools, not default linters or compiler errors, placing this squarely at d5.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix describes adding a label() method, implementing interfaces, and swapping from() for tryFrom() — a small, localised refactor within the enum and its call sites. It touches a bounded set of places rather than spanning multiple unrelated files, so e3 fits better than e5.

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

Closest to 'localised tax' (b3). The choice applies across web, cli, and queue-worker contexts (broad applies_to), but the structural debt is confined to the enum definitions and their direct consumers. Moving logic into enum methods reduces scattered switch statements, so the ongoing maintenance tax is localised rather than codebase-wide.

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

Closest to 'minor surprise' (t3). The misconception is that enum methods can modify the case's value, but the immutability of enum cases is a well-documented PHP 8.1 property. Developers familiar with enums from other languages (Java, Kotlin) may be briefly surprised, but the constraint is unsurprising once learned and does not contradict deeply held intuitions — one edge case rather than a systematic trap.

About DEBT scoring →

Also Known As

enum methods enum interface PHP backed enum methods

TL;DR

PHP 8.1 enums support methods, interface implementation, constants, and static factory methods — making them full-featured types, not just value lists.

Explanation

PHP 8.1 enums go beyond simple value lists. Pure enums (no backing type) and backed enums (string or int) can both implement interfaces, declare constants, and define methods. Methods have access to $this->name and $this->value. Static methods can act as factory/lookup helpers. Enums cannot have mutable properties but can use readonly static properties. Backed enums provide from() (throws on invalid value) and tryFrom() (returns null). Enums implement UnitEnum (all) and BackedEnum (backed) interfaces. Use cases: status types with behaviour (Status::Active->label()), permission sets implementing a Grantable interface, and self-describing command/event types.

Common Misconception

PHP enum methods can modify the enum case's value. Enum cases are immutable constants — methods can compute derived values or implement interface methods but cannot alter the case itself. Backed enum values are fixed at declaration and cannot change at runtime.

Why It Matters

PHP 8.1 enums can define methods — adding behaviour directly to cases (labels, colours, permissions) keeps enum logic with the enum rather than scattered in switch statements across the codebase.

Common Mistakes

  • Putting enum-related logic in external services or switch statements instead of enum methods.
  • Defining mutable state inside enums — enums are value types and must be stateless.
  • Not implementing interfaces on enums — they can implement interfaces to participate in type contracts.
  • Using match($enum) externally when the enum could provide the same behaviour through a method.

Code Examples

✗ Vulnerable
// Logic scattered outside enum:
enum Status { case Active; case Inactive; case Banned; }

function getLabel(Status $s): string {
    return match($s) {
        Status::Active => 'Active', Status::Inactive => 'Inactive', Status::Banned => 'Banned'
    };
}
// Better: add label(): string method to the enum itself
✓ Fixed
enum Status: string implements HasLabel {
  case Active   = 'active';
  case Inactive = 'inactive';

  public function label(): string {
    return match($this) {
      Status::Active   => 'Active User',
      Status::Inactive => 'Deactivated',
    };
  }
}

Tags


Added 15 Mar 2026
Edited 22 Mar 2026
Views 23
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 1 ping T 0 pings W 2 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F
No pings yet today
No pings yesterday
Amazonbot 7 Perplexity 4 Unknown AI 3 Google 2 Ahrefs 2 ChatGPT 2
crawler 17 crawler_json 2 pre-tracking 1
DEV INTEL Tools & Severity
🟢 Low ⚙ Fix effort: Low
⚡ Quick Fix
Add a label() method, implement interfaces, and use from()/tryFrom() for safe string-to-enum conversion — use tryFrom() when the source is untrusted user input
📦 Applies To
PHP 8.1+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Enum::from() on user-controlled value that may not match — should be tryFrom() with null handling
Auto-detectable: ✓ Yes phpstan psalm
⚠ Related Problems
🤖 AI Agent
Confidence: Low False Positives: High ✗ Manual fix Fix: Medium Context: Class

✓ schema.org compliant