Summary - Modern PHP
Build a modern state machine with readonly, enum, match and named arguments.
A state machine with modern PHP
This group covered PHP 8+ features: readonly properties, enum, the match expression, named arguments, Fiber and first-class callable (...).
Combine them to build immutable, type-safe models. Define an order's state with enum, wrap it in a readonly class and label it with match.
Named arguments make the call readable. In the type system, intersection types bind a parameter to multiple interfaces, e.g. function handle(HasId & HasName $x).
Exercise Order state machine
Define an int backed enum OrderStatus: Pending = 1, Shipped = 2, Delivered = 3.
Write a readonly class Order using constructor property promotion for int $id and OrderStatus $status. Write label(Order $o): string with match($o->status); return "Shipped" for Shipped.
The call below should print Shipped.
Show example solution
enum OrderStatus: int {
case Pending = 1;
case Shipped = 2;
case Delivered = 3;
}
readonly class Order {
public function __construct(
public int $id,
public OrderStatus $status
) {}
}
function label(Order $o): string {
return match($o->status) {
OrderStatus::Pending => "Pending",
OrderStatus::Shipped => "Shipped",
OrderStatus::Delivered => "Delivered",
};
}
$o = new Order(id: 7, status: OrderStatus::Shipped);
echo label($o);
Test yourself
-
Best representation for order state?
- string
- int constant
- array
- backed enum
Show answer
backed enum — Correct. A backed enum keeps state names and values together; it is type-safe and matches cleanly with switch/match.
-
The match arm arrow
$label = match($o->status) { OrderStatus::Shipped ____ "Shipped", default => "Unknown", };Show answer
$label = match($o->status) { OrderStatus::Shipped => "Shipped", default => "Unknown", }; -
Feature - role pairing
- readonly
- writable once
- enum
- type-safe constants
- match
- value-returning conditional
- ?->
- null-safe access