Skip to main content

Enums

Chapter Overview

In this chapter you will learn:

  • What Enums are
  • Why Enums exist
  • Problems Enums solve
  • Unit Enums
  • Backed Enums
  • Enum Methods
  • Enum Interfaces
  • Enum Traits
  • Enum Best Practices
  • Enterprise Examples
  • PocketMine Examples
  • Projects and Exercises

Introduction

Enums were introduced in:

PHP 8.1

Enums are one of the biggest additions to PHP.

Before Enums existed, developers used:

const ADMIN = "admin";
const MOD = "mod";
const PLAYER = "player";

This created many problems.


What is an Enum?

Enum means:

Enumeration

An enum is a fixed list of possible values.


Example

Traffic Lights:

RED
YELLOW
GREEN

Only these values exist.

You cannot create:

PURPLE
BLUE
BLACK

because they are invalid.

This is exactly how enums work.


Real Life Examples

Enums are everywhere.

Examples:

Game Modes
Payment Status
User Roles
Packet Types
Permission Levels
Order Status
Server States

Problem Without Enums

Example:

$status = "compeleted";

Notice:

compeleted

Typo.

PHP accepts it.

Your application breaks.


Another example:

$rank = "admn";

Again invalid.

No error.


Enums Solve This

enum Rank {

case ADMIN;
case MODERATOR;
case PLAYER;

}

Now:

$rank = Rank::ADMIN;

No typos.

Much safer.


Benefits of Enums

✅ Type Safety

✅ Better Readability

✅ Auto Completion

✅ Fewer Bugs

✅ Cleaner Architecture


Basic Syntax


Unit Enum

enum Rank {

case OWNER;
case ADMIN;
case PLAYER;

}

Usage:

$rank =
Rank::OWNER;

Comparison:

if (
$rank === Rank::OWNER
) {

}

Visualization

Rank

├── OWNER
├── ADMIN
└── PLAYER

Unit Enums

Unit enums contain:

Cases only.

No values.


Example:

enum ServerState {

case STARTING;
case RUNNING;
case STOPPING;
case OFFLINE;

}

Usage:

$state =
ServerState::RUNNING;

Why Useful?

Because:

Only valid states can exist.

Backed Enums

Backed enums store values.


Example:

enum Rank : string {

case OWNER = "owner";
case ADMIN = "admin";
case PLAYER = "player";

}

Usage:

echo
Rank::OWNER->value;

Output:

owner

Integer Backed Enum

enum Permission : int {

case PLAYER = 1;
case VIP = 2;
case ADMIN = 3;

}

Output:

Permission::ADMIN->value

Result:

3

Why Backed Enums Exist

Useful for:

Databases
Configurations
JSON APIs
Packets
Files

Example Database

Database:

rank
-----
admin

PHP:

$rank =
Rank::from(
"admin"
);

Enum Methods

Enums can have methods.


Example:

enum Rank {

case OWNER;
case ADMIN;
case PLAYER;

public function color()
: string {

return match($this) {

self::OWNER =>
"gold",

self::ADMIN =>
"red",

self::PLAYER =>
"gray"

};

}

}

Usage:

echo
Rank::OWNER
->color();

Output:

gold

Match Expressions

Enums work perfectly with:

match()

Example:

$message =
match($rank) {

Rank::OWNER =>
"Owner",

Rank::ADMIN =>
"Admin",

Rank::PLAYER =>
"Player"

};

Enum Static Methods

Example:

enum Rank {

case OWNER;
case ADMIN;

public static function default()
: self {

return self::PLAYER;

}

}

Enum Interfaces

Enums can implement interfaces.


Example:

interface Colorable {

public function color()
: string;

}

Enum:

enum Rank
implements Colorable {

case OWNER;
case ADMIN;

public function color()
: string {

return "red";

}

}

Enum Traits

Enums can use traits.


Example:

trait LabelTrait {

public function label()
: string {

return ucfirst(
$this->name
);

}

}

Usage:

enum Rank {

use LabelTrait;

case OWNER;
case ADMIN;

}

Enum Properties?

Enums CANNOT contain properties.

Invalid:

enum Rank {

public string $name;

}

Error.


Why?

Enums are intended to be:

Immutable.

Enum Methods Available

PHP automatically provides:


name

Rank::OWNER->name

Output:

OWNER

value

For backed enums:

Rank::OWNER->value

Output:

owner

from()

Converts value to enum.


Example:

Rank::from(
"owner"
);

tryFrom()

Safer version.


Example:

Rank::tryFrom(
"invalid"
);

Output:

null

instead of exception.


Example

$rank =
Rank::tryFrom(
$databaseValue
);

if (
$rank === null
) {

}

cases()

Returns all enum cases.


Example:

Rank::cases();

Output:

[
Rank::OWNER,
Rank::ADMIN,
Rank::PLAYER
]

Usage

Creating dropdown menus.


Example:

foreach(
Rank::cases()
as $rank
)
{
echo
$rank->name;
}

Enterprise Examples


User Roles

enum UserRole {

case USER;
case MODERATOR;
case ADMIN;
case OWNER;

}

Order Status

enum OrderStatus {

case PENDING;
case PAID;
case CANCELLED;
case REFUNDED;

}

Payment Status

enum PaymentStatus {

case CREATED;
case PROCESSING;
case SUCCESS;
case FAILED;

}

API Example

enum ApiStatus
: int {

case SUCCESS = 200;
case ERROR = 500;

}

PocketMine Examples

Enums are extremely useful for:


Server State

enum ServerState {

case STARTING;
case RUNNING;
case STOPPING;

}

Player Rank

enum Rank {

case PLAYER;
case VIP;
case STAFF;
case ADMIN;

}

Game State

enum GameState {

case WAITING;
case STARTING;
case PLAYING;
case ENDING;

}

Arena State

enum ArenaStatus {

case CLOSED;
case OPEN;
case RESTARTING;

}

Packet Types

enum PacketType
: int {

case LOGIN = 1;
case CHAT = 2;
case MOVE = 3;

}

Why Enums are Amazing for Game Servers

Without enums:

if (
$state == "plaing"
)

Typo.

Bug.


With enums:

if (
$state ===
GameState::PLAYING
)

Perfectly safe.


Enums vs Constants


Constants

class Rank {

public const ADMIN =
"admin";

}

Problems:

❌ No type safety.

❌ Can pass invalid values.


Enums

Rank::ADMIN

Only valid values exist.


Comparison

FeatureConstantsEnums
Type Safe
Methods
Cases()
Interfaces
Match Support

Common Beginner Mistakes


Using Strings Everywhere

Bad:

$rank = "admin";

Using Integers

Bad:

$status = 4;

Nobody knows what 4 means.


Overusing Enums

Not everything needs enums.


Good Uses

✅ States

✅ Statuses

✅ Roles

✅ Permissions

✅ Packet Types


Bad Uses

❌ Usernames

❌ Dynamic values

❌ Database records


Best Practices

✅ Use enums for finite values.

✅ Prefer backed enums for databases.

✅ Add helper methods.

✅ Use match expressions.


Exercises


Exercise 1

Create:

enum Rank {

}

Cases:

OWNER
ADMIN
PLAYER

Exercise 2

Create:

enum GameState {

}

Exercise 3

Create:

enum PermissionLevel
: int {

}

Mini Project

Create:

ZyroNetwork Rank System

Enums:

Rank
GameState
ServerState
PermissionLevel

Methods:

color()
prefix()
permissions()

Interview Questions


What is an Enum?

A fixed set of possible values.


When were enums introduced?

PHP 8.1

Difference between Unit and Backed Enums?

Unit:

No values.

Backed:

Contain values.

Can enums have methods?

Yes.


Can enums have properties?

No.


Why use enums?

For type safety and cleaner code.


Summary

Enums provide:

✅ Type Safety

✅ Better Architecture

✅ Fewer Bugs

✅ Cleaner APIs

✅ Better IDE Support

✅ Excellent State Management

Modern PHP applications heavily rely on enums.


References

https://www.php.net/manual/en/language.enumerations.php


Next Chapter

➡ Namespaces

➡ Autoloading

➡ Dependency Injection

➡ SOLID Principles