Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

PHP 8.1 enums let you represent a fixed set of choices as a real type instead of passing loosely checked strings or integers. Use a pure enum when the case itself is the value inside your application; use a backed enum when each case also needs a stable string or integer representation for a database or other external contract.

What is an enum in PHP 8.1?

PHP 8.1, released on 25 November 2021, introduced enumerations as a typed alternative to a loose collection of constants. An enum defines a custom type whose possible values are limited to its declared cases. Each case is a single-instance object, so a function can require a Status rather than accept any string that happens to look like a status.

enum Status
{
    case Draft;
    case Published;
    case Archived;
}

function publish(Status $status): void
{
    // Only a Status case can be passed here.
}

publish(Status::Published);

PHP 8.1 release announcement; PHP Manual: Enumerations overview.

When should you use a pure enum or a backed enum?

A pure enum has cases but no scalar values. Choose one when the case identity is sufficient within your application, such as a workflow state used in typed application logic. A backed enum gives each case a unique, explicitly declared scalar value. PHP 8.1 allows one backing type per enum: string or int.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
enum OrderStatus: string
{
    case Pending = 'pending';
    case Paid = 'paid';
    case Cancelled = 'cancelled';
}

Use a backing value when it is part of an external contract—for example, a database column, message, or API representation. Keep the enum object as the typed value within application code, and use its value property when crossing that boundary. The distinction is that the enum case remains the domain object; the backing scalar is its external representation.

Choice Cases and type safety Scalar representation Suitable use
Constants A set of named values, but a parameter accepting a string or integer can still receive other values of that type. Whatever values the constants define. Named values where a closed, enum-typed parameter is not required.
Pure enum Closed set of singleton case objects; enum-typed parameters reject arbitrary strings and integers. None built in. Choices whose case identity is enough inside the application.
Backed enum Closed set of singleton case objects; enum-typed parameters reject arbitrary strings and integers. One unique, explicitly assigned int or string per case. Choices that need a defined scalar for persistence or another external contract.

The PHP manual describes enums as a way to define a custom type limited to a discrete number of possible values. The accepted PHP Enumerations RFC frames the design goal as making invalid states unrepresentable.

How do you get enum cases and convert scalar input?

Every enum provides cases(), which returns its declared cases in declaration order. Backed enums also provide from() and tryFrom() for looking up a case by its backing scalar:

  • from(int|string): static returns the matching case. If no case matches, PHP throws ValueError.
  • tryFrom(int|string): ?static returns the matching case, or null if the scalar is unknown.

Use tryFrom() when input may be invalid and the caller needs to validate it or choose an explicit fallback:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
$status = OrderStatus::tryFrom($request->input('status'));

if ($status === null) {
    // Report a validation error or choose an explicit fallback.
}

Use from() when an unknown value means an invariant has been broken and should fail immediately:

$status = OrderStatus::from($storedStatus);

Do not treat from() as a validation method that quietly handles unfamiliar values: its failure is an exception. For request, file, or database data whose validity is uncertain, tryFrom() makes the unknown-value branch explicit. The generated methods and their behavior are documented in the PHP Manual: Backed Enumerations.

Can enums have methods and implement interfaces?

Yes. Enums can define ordinary methods and implement interfaces. This lets an enum own behavior associated with its cases instead of requiring callers to maintain separate switch statements.

interface Labelled
{
    public function label(): string;
}

enum Priority implements Labelled
{
    case Low;
    case High;

    public function label(): string
    {
        return match ($this) {
            self::Low => 'Low priority',
            self::High => 'High priority',
        };
    }
}

Because cases are objects, code typed against Labelled can accept Priority::Low or Priority::High when the enum implements that interface.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How do PHP enums behave in arrays, JSON, and serialization?

For a backed enum, the read-only value property exposes its scalar. Converting an enum to an array has a separate result: a pure enum has a name key, while a backed enum has both name and value.

JSON behavior is not the same as PHP serialization. By default, a pure enum raises an error when encoded as JSON; a backed enum is represented by its backing scalar. Implementing JsonSerializable lets you define a different JSON shape, such as an object containing both a case name and a value. Choose that shape deliberately if it is part of a public API contract; do not assume every enum automatically becomes a string.

PHP’s enum serialization has its own representation: unserializing an enum restores the existing singleton case. These array, JSON, and serialization rules are described in the PHP Manual: Enumeration serialization and the PHP Enumerations RFC.

How should you choose and use an enum at an application boundary?

  • Choose a pure enum if application logic needs a closed set of typed cases but no built-in scalar mapping.
  • Choose a backed enum if a stable string or integer is part of the storage or transport contract.
  • Convert external input into the enum at the boundary, then pass the typed case through application logic rather than carrying unvalidated scalars throughout the code.
  • Use tryFrom() when unknown input needs an explicit validation path; use from() when an unknown value should throw.
  • Document JSON output explicitly, especially if clients depend on a custom object shape rather than the backed scalar.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.