Enumerations in PHP: from switch to Enum (complete guide)

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Why "Enumerations on PHP" is a million-dollar question?

\n\n

If you've ever Googled "enumerations on PHP", you know: before PHP 8.1 was released, this topic was a real quest. Developers reinvented the wheel with constants, abstract classes, and clever traits. Stack Overflow was full of questions like "How to emulate Enum in PHP?", and answers gathered hundreds of upvotes.

\n\n

But times have changed. Starting with PHP 8.1, enumerations (Enum) became a native part of the language. And this is not just syntactic sugar — it's a powerful tool for writing clean, safe, and self-documenting code.

\n\n

In this article, we'll cover everything: from the classic approach with constants to modern Enums, with real examples and best practices. Let's go!

\n\n

The problem: how PHP developers lived before PHP 8.1

\n\n

Before the advent of native enumerations, we had two main paths: class constants and "hacks" with abstract classes. Let's look at both.

\n\n

Approach #1: Class constants (the most popular)

\n\n
class OrderStatus {\n    const PENDING = 'pending';\n    const PROCESSING = 'processing';\n    const SHIPPED = 'shipped';\n    const DELIVERED = 'delivered';\n    const CANCELLED = 'cancelled';\n}\n\n// Usage\n$status = OrderStatus::PENDING;\nif ($status === OrderStatus::PROCESSING) {\n    echo 'Order is being processed';\n}
\n\n

Pros: simplicity, clarity, autocomplete in IDE.

\n

Cons: lack of typing. Anyone can pass the string 'invalid_status' — and PHP won't complain.

\n\n

Approach #2: Abstract class + private constructor

\n\n

Advanced developers went further:

\n\n
abstract class OrderStatus {\n    private function __construct() {}\n    \n    public static function pending(): self {\n        return new class extends OrderStatus {};\n    }\n    public static function processing(): self {\n        return new class extends OrderStatus {};\n    }\n    // ... remaining statuses\n}
\n\n

It worked, but the code became bloated. And it was still an emulation, not real language support.

\n\n

Native Enum in PHP 8.1: a revolution

\n\n

With the release of PHP 8.1, the "enumerations on PHP" problem was solved once and for all. Now enumerations are full-fledged types that:

\n\n
    \n
  • Support strict typing
  • \n
  • Have built-in methods (name, value, cases())
  • \n
  • Can implement interfaces
  • \n
  • Support traits
  • \n
  • Integrate with match and switch
  • \n
\n\n

Basic Enum syntax in PHP

\n\n
enum OrderStatus {\n    case Pending;\n    case Processing;\n    case Shipped;\n    case Delivered;\n    case Cancelled;\n}\n\n// Usage\n$status = OrderStatus::Pending;\necho $status->name; // 'Pending'
\n\n

Simple and elegant. But this is just the beginning.

\n\n

Enum types: pure and backed

\n\n

PHP supports two types of enumerations:

\n\n

1. Pure Enum

\n

Without binding to specific values. Ideal for flags, states, types.

\n\n
enum UserRole {\n    case Admin;\n    case Editor;\n    case Viewer;\n}\n\nfunction checkAccess(UserRole $role): bool {\n    return match($role) {\n        UserRole::Admin => true,\n        UserRole::Editor => true,\n        UserRole::Viewer => false,\n    };\n}
\n\n

2. Backed Enum

\n

When you need to map an enum to a specific value (string or integer).

\n\n
enum OrderStatus: string {\n    case Pending = 'pending';\n    case Processing = 'processing';\n    case Shipped = 'shipped';\n    case Delivered = 'delivered';\n    case Cancelled = 'cancelled';\n}\n\n// Get the value\n$status = OrderStatus::Shipped;\necho $status->value; // 'shipped'\n\n// Create from a value\n$                

Blogs

Book Recommendations