Overview of PHP Enums and archtechx/enums
PHP 8.1 introduced native enumerations (enums), which define a type-safe set of named values for modeling fixed sets of constants, such as statuses or roles. Enums can be pure (no associated values) or backed (tied to string or integer values). The match expression, introduced in PHP 8.0, provides a concise, type-safe alternative to switch statements.
The archtechx/enums package extends native enums with traits that simplify common tasks, such as retrieving case names, values, or metadata, and making enums invokable. These features reduce boilerplate code and improve developer experience.
Key Features of archtechx/enums:
- InvokableCases: Allows invoking enum cases statically or on instance to get their values(backed enums) or names(pure enums) without ->value.
- Names: Returns an array of enum case names.
- Values: Returns an array of enum case values (backed enums) or names (pure enums).
- Options: Returns an associative array of case names and values (backed enums) or names (pure enums).
- From: Adds from() and tryFrom() for reverse lookup by name for pure and backed enums.
Installation
Install the package via Composer:
composer require archtechx/enums
No additional setup is required, as the package provides traits to include in your enums. It requires PHP 8.1+.
Guide to PHP Enums with archtechx/enums Features
Below is a comprehensive guide to using PHP enums, the match expression, and the archtechx/enums package, with examples demonstrating each trait.
1. Basic Enum Usage with match:
First, let’s review a basic enum with a match expression, then enhance it with archtechx/enums traits.
Pure Enum Example:
<?php
enum Status {
case Pending;
case Approved;
case Rejected;
}
function getStatusMessage(Status $status): string {
return match ($status) {
Status::Pending => 'Your request is pending.',
Status::Approved => 'Your request is approved!',
Status::Rejected => 'Your request was rejected.',
};
}
$status = Status::Approved;
echo getStatusMessage($status); // Output: Your request is approved!
Backed Enum Example:
<?php
enum Status: string {
case Pending = 'pending';
case Approved = 'approved';
case Rejected = 'rejected';
}
function getStatusMessage(Status $status): string {
return match ($status->value) {
'pending' => 'Your request is pending.',
'approved' => 'Your request is approved!',
'rejected' => 'Your request was rejected.',
};
}
$status = Status::Approved;
echo getStatusMessage($status); // Output: Your request is approved!
2. Enhancing Enums with archtechx/enums Traits:
The archtechx/enums package provides traits to simplify enum usage. Below are examples of each trait, integrated into a practical order status system.
Trait 1: InvokableCasesThe InvokableCases trait allows you to invoke enum cases statically (e.g., Status::Pending()) or on instances (e.g., $status()) to get the backed value (for backed enums) or the case name (for pure enums), eliminating the need to use ->value.
Example: InvokableCases
<?php
use ArchTech\Enums\InvokableCases;
enum TaskStatus: int {
use InvokableCases;
case INCOMPLETE = 0;
case COMPLETED = 1;
case CANCELED = 2;
}
enum Role {
use InvokableCases;
case ADMINISTRATOR;
case SUBSCRIBER;
case GUEST;
}
// Static invocation
echo TaskStatus::COMPLETED() . "\n"; // Output: 1
echo Role::ADMINISTRATOR() . "\n"; // Output: ADMINISTRATOR
// Instance invocation
$status = TaskStatus::COMPLETED;
echo $status() . "\n"; // Output: 1
$role = Role::SUBSCRIBER;
echo $role() . "\n"; // Output: SUBSCRIBER
// Usage in a function
function updateTask(TaskStatus $status): string {
return "Task status updated to: " . $status();
}
echo updateTask(TaskStatus::COMPLETED) . "\n";
// Output: Task status updated to: 1
Benefit: Simplifies accessing enum values without ->value, improving readability and IDE support (auto suggestions for cases).
Trait 2: Names
The Names trait adds a names() method to return an array of enum case names.
Example: Names
<?php
use ArchTech\Enums\Names;
enum TaskStatus: int {
use Names;
case INCOMPLETE = 0;
case COMPLETED = 1;
case CANCELED = 2;
}
enum Role {
use Names;
case ADMINISTRATOR;
case SUBSCRIBER;
case GUEST;
}
print_r(TaskStatus::names());
// Output: ['INCOMPLETE', 'COMPLETED', 'CANCELED']
print_r(Role::names());
// Output: ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
Benefit: Easily retrieve case names for display in dropdowns, logs, or debugging.
Trait 3: Values
The Values trait adds a values() method to return an array of backed values (for backed enums) or case names (for pure enums).
Example: Values
<?php
use ArchTech\Enums\Values;
enum TaskStatus: int {
use Values;
case INCOMPLETE = 0;
case COMPLETED = 1;
case CANCELED = 2;
}
enum Role {
use Values;
case ADMINISTRATOR;
case SUBSCRIBER;
case GUEST;
}
print_r(TaskStatus::values());
// Output: [0, 1, 2]
print_r(Role::values());
// Output: ['ADMINISTRATOR', 'SUBSCRIBER', 'GUEST']
Benefit: Useful for retrieving values to store in databases or use in APIs.
Trait 4: Options
The Options trait adds an options() method to return an associative array of case names and values (for backed enums) or names (for pure enums).
Example: Options
<?php
use ArchTech\Enums\Options;
enum TaskStatus: int {
use Options;
case INCOMPLETE = 0;
case COMPLETED = 1;
case CANCELED = 2;
}
print_r(TaskStatus::options());
// Output: ['INCOMPLETE' => 0, 'COMPLETED' => 1, 'CANCELED' => 2]
Benefit: Ideal for generating key-value pairs for form select inputs or configuration arrays.
use stringOptions():
The trait also adds the stringOptions() method that can be used for generating convenient string representations of your enum options:
// returns "INCOMPLETE => 0, COMPLETED => 1, CANCELED => 2"
TaskStatus::stringOptions(fn ($name, $value) => "$name => $value", ', ');
For pure enums (non-backed), the name is used in place of $value (meaning that both $name and $value are the same).
Both arguments for this method are optional, the glue defaults to \n and the callback defaults to generating HTML <option> tags:
<?php
require __DIR__ . '/vendor/autoload.php';
use ArchTech\Enums\{Options};
enum OrderStatus: string {
use Options;
case Pending = 'pending';
case Processing = 'processing';
case Shipped = 'shipped';
case Delivered = 'delivered';
case Cancelled = 'cancelled';
}
enum TaskStatus: int {
use Options;
case INCOMPLETE = 0;
case COMPLETED = 1;
case CANCELED = 2;
}
echo TaskStatus::stringOptions();
// <option value="0">Incomplete</option>
// <option value="1">Completed</option>
// <option value="2">Canceled</option>
echo OrderStatus::stringOptions();
//<option value="pending">Pending</option>\n
//<option value="processing">Processing</option>\n
//<option value="shipped">Shipped</option>\n
//<option value="delivered">Delivered</option>\n
//<option value="cancelled">Cancelled</option>
The From trait adds fromName(), tryFromName(), from(), and tryFrom() methods to convert names or values to enum cases, extending PHP’s native from() and tryFrom() for both pure and backed enums.
Example: From
<?php
use ArchTech\Enums\From;
enum BloodType: string {
use From;
case A = 'A型';
case B = 'B型';
case AB = 'AB型';
case O = 'O型';
}
// Convert name to enum
$bloodType = BloodType::fromName('B');
echo $bloodType->value; // Output: B型
// Convert value to enum
$bloodType = BloodType::from('O型');
echo $bloodType->name; // Output: O
// Handle invalid inputs
$bloodType = BloodType::tryFromName('X') ?? BloodType::O;
echo $bloodType->value; // Output: O型
Benefit: Simplifies reverse lookups, especially for pure enums, and provides safe handling of invalid inputs.
Best Practices with archtechx/enums
- Use InvokableCases for Simplicity: Avoid ->value in database or API interactions by invoking enums directly.
- Leverage Options for Forms: Use options() to populate select inputs in forms.
- Combine with match: Use match for clean, type-safe logic with enum cases.
- Handle Invalid Inputs: Use tryFrom() or tryFromName() to gracefully handle invalid values.
- Organize Enums: Place enums in an app/Enums directory for consistency in Laravel projects.
This guide demonstrates how the archtechx/enums package enhances PHP enums with practical, real-world examples. For more details, check the package’s GitHub repository: https://github.com/archtechx/enums If you need further examples or specific use cases, let me know!
If you found this helpful, feel free to share or drop a comment. Happy coding with Laravel! 🧱✨
Free resources for this topic
Code snippets and fixes for this topic
Get one practical tip every week
New tutorials, fixes and free cheat sheets from DEV Talk, straight to your inbox. No spam, unsubscribe in one click.
Free download: Laravel interview questions (PDF)
Have a question about this post?
Ask the community: other developers and the author can answer.
Get notified about new articles
One click, no email needed. Turn it off anytime with the bell at the top.
Get new articles on your iPhone
Add DEV Talk to your Home Screen, open it, then tap the bell.
Enjoying the content?
If this article helped you, you can support the author with a coffee. It keeps new posts coming.
Comments 0
No comments yet
Be the first to share your thoughts.